4 * Copyright David W. Metcalfe, 1994
8 static char Copyright[] = "Copyright David W. Metcalfe, 1994";
20 /* #define DEBUG_EDIT */
21 /* #undef DEBUG_EDIT */
25 #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
26 SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
27 GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
29 #define MAXTEXTLEN 30000 /* maximum text buffer length */
30 #define EDITLEN 1024 /* starting length for multi-line control */
31 #define ENTRYLEN 256 /* starting length for single line control */
32 #define GROWLENGTH 64 /* buffers grow by this much */
34 #define HSCROLLDIM (ClientWidth(wndPtr) / 3)
35 /* "line" dimension for horizontal scroll */
39 int wlines
; /* number of lines of text */
40 int wtop
; /* top line that is displayed */
41 int wleft
; /* left pixel that is displayed */
42 unsigned int textlen
; /* text buffer length */
43 int textwidth
; /* width of longest line in pixels */
44 RECT fmtrc
; /* rectangle in which to format text */
45 int txtht
; /* height of text line in pixels */
46 HANDLE hText
; /* handle to text buffer */
47 HANDLE hCharWidths
; /* widths of chars in font */
48 HANDLE hTextPtrs
; /* list of line offsets */
49 HANDLE hBlankLine
; /* to fill blank lines quickly */
50 int CurrCol
; /* current column */
51 int CurrLine
; /* current line */
52 int WndCol
; /* current window column */
53 int WndRow
; /* current window row */
54 BOOL TextChanged
; /* TRUE if text has changed */
55 BOOL PaintBkgd
; /* paint control background */
56 unsigned int MaxTextLen
; /* maximum text buffer length */
57 int SelBegLine
; /* beginning line of selection */
58 int SelBegCol
; /* beginning column of selection */
59 int SelEndLine
; /* ending line of selection */
60 int SelEndCol
; /* ending column of selection */
61 HFONT hFont
; /* handle of current font (if not default) */
62 HANDLE hDeletedText
; /* handle to deleted txet buffer for undo */
63 int DeletedLength
; /* length of deleted text */
64 int DeletedCurrLine
; /* starting line from which text was deleted */
65 int DeletedCurrCol
; /* starting col from which text was deleted */
66 int NumTabStops
; /* number of tab stops in buffer hTabStops */
67 HANDLE hTabStops
; /* handle of tab stops buffer */
71 #define ClientWidth(wndPtr) \
72 (wndPtr->rectClient.right > wndPtr->rectClient.left ? \
73 wndPtr->rectClient.right - wndPtr->rectClient.left : 0)
74 #define ClientHeight(wndPtr, es) \
75 (wndPtr->rectClient.bottom > wndPtr->rectClient.top ? \
76 (wndPtr->rectClient.bottom - wndPtr->rectClient.top) / es->txtht : 0)
77 #define EditBufLen(wndPtr) (wndPtr->dwStyle & ES_MULTILINE \
79 #define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol)
80 #define SelMarked(es) (es->SelBegLine != 0 || es->SelBegCol != 0 || \
81 es->SelEndLine != 0 || es->SelEndCol != 0)
82 #define ROUNDUP(numer, denom) (((numer) % (denom)) \
83 ? ((((numer) + (denom)) / (denom)) * (denom)) \
86 /* macros to access window styles */
87 #define IsAutoVScroll() (wndPtr->dwStyle & ES_AUTOVSCROLL)
88 #define IsAutoHScroll() (wndPtr->dwStyle & ES_AUTOHSCROLL)
89 #define IsMultiLine() (wndPtr->dwStyle & ES_MULTILINE)
90 #define IsVScrollBar() (wndPtr->dwStyle & WS_VSCROLL)
91 #define IsHScrollBar() (wndPtr->dwStyle & WS_HSCROLL)
93 /* internal variables */
94 static BOOL TextMarking
; /* TRUE if text marking in progress */
95 static BOOL ButtonDown
; /* TRUE if left mouse button down */
96 static int ButtonRow
; /* row in text buffer when button pressed */
97 static int ButtonCol
; /* col in text buffer when button pressed */
100 LONG
EditWndProc(HWND hWnd
, WORD uMsg
, WORD wParam
, LONG lParam
);
101 long EDIT_NCCreateMsg(HWND hwnd
, LONG lParam
);
102 long EDIT_CreateMsg(HWND hwnd
, LONG lParam
);
103 void EDIT_ClearTextPointers(HWND hwnd
);
104 void EDIT_BuildTextPointers(HWND hwnd
);
105 void EDIT_ModTextPointers(HWND hwnd
, int lineno
, int var
);
106 void EDIT_PaintMsg(HWND hwnd
);
107 HANDLE
EDIT_GetTextLine(HWND hwnd
, int selection
);
108 char *EDIT_TextLine(HWND hwnd
, int sel
);
109 int EDIT_StrLength(HWND hwnd
, unsigned char *str
, int len
, int pcol
);
110 int EDIT_LineLength(HWND hwnd
, int num
);
111 void EDIT_WriteTextLine(HWND hwnd
, RECT
*rc
, int y
);
112 void EDIT_WriteText(HWND hwnd
, char *lp
, int off
, int len
, int row
,
113 int col
, RECT
*rc
, BOOL blank
, BOOL reverse
);
114 HANDLE
EDIT_GetStr(HWND hwnd
, char *lp
, int off
, int len
, int *diff
);
115 void EDIT_CharMsg(HWND hwnd
, WORD wParam
);
116 void EDIT_KeyTyped(HWND hwnd
, short ch
);
117 int EDIT_CharWidth(HWND hwnd
, short ch
, int pcol
);
118 int EDIT_GetNextTabStop(HWND hwnd
, int pcol
);
119 void EDIT_Forward(HWND hwnd
);
120 void EDIT_Downward(HWND hwnd
);
121 void EDIT_Upward(HWND hwnd
);
122 void EDIT_Backward(HWND hwnd
);
123 void EDIT_End(HWND hwnd
);
124 void EDIT_Home(HWND hwnd
);
125 void EDIT_StickEnd(HWND hwnd
);
126 void EDIT_KeyDownMsg(HWND hwnd
, WORD wParam
);
127 void EDIT_KeyHScroll(HWND hwnd
, WORD opt
);
128 void EDIT_KeyVScrollLine(HWND hwnd
, WORD opt
);
129 void EDIT_KeyVScrollPage(HWND hwnd
, WORD opt
);
130 void EDIT_KeyVScrollDoc(HWND hwnd
, WORD opt
);
131 int EDIT_ComputeVScrollPos(HWND hwnd
);
132 int EDIT_ComputeHScrollPos(HWND hwnd
);
133 void EDIT_DelKey(HWND hwnd
);
134 void EDIT_VScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
135 void EDIT_VScrollLine(HWND hwnd
, WORD opt
);
136 void EDIT_VScrollPage(HWND hwnd
, WORD opt
);
137 void EDIT_HScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
138 void EDIT_SizeMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
139 void EDIT_LButtonDownMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
140 void EDIT_MouseMoveMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
141 int EDIT_PixelToChar(HWND hwnd
, int row
, int *pixel
);
142 LONG
EDIT_SetTextMsg(HWND hwnd
, LONG lParam
);
143 void EDIT_ClearText(HWND hwnd
);
144 void EDIT_SetSelMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
145 void EDIT_GetLineCol(HWND hwnd
, int off
, int *line
, int *col
);
146 void EDIT_DeleteSel(HWND hwnd
);
147 void EDIT_ClearSel(HWND hwnd
);
148 int EDIT_TextLineNumber(HWND hwnd
, char *lp
);
149 void EDIT_SetAnchor(HWND hwnd
, int row
, int col
);
150 void EDIT_ExtendSel(HWND hwnd
, int x
, int y
);
151 void EDIT_WriteSel(HWND hwnd
, int y
, int start
, int end
);
152 void EDIT_StopMarking(HWND hwnd
);
153 LONG
EDIT_GetLineMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
154 LONG
EDIT_GetSelMsg(HWND hwnd
);
155 void EDIT_ReplaceSel(HWND hwnd
, LONG lParam
);
156 void EDIT_InsertText(HWND hwnd
, char *str
, int len
);
157 LONG
EDIT_LineFromCharMsg(HWND hwnd
, WORD wParam
);
158 LONG
EDIT_LineIndexMsg(HWND hwnd
, WORD wParam
);
159 LONG
EDIT_LineLengthMsg(HWND hwnd
, WORD wParam
);
160 void EDIT_SetFont(HWND hwnd
, WORD wParam
, LONG lParam
);
161 void EDIT_SaveDeletedText(HWND hwnd
, char *deltext
, int len
, int line
,
163 void EDIT_ClearDeletedText(HWND hwnd
);
164 LONG
EDIT_UndoMsg(HWND hwnd
);
165 unsigned int EDIT_HeapAlloc(HWND hwnd
, int bytes
);
166 void *EDIT_HeapAddr(HWND hwnd
, unsigned int handle
);
167 unsigned int EDIT_HeapReAlloc(HWND hwnd
, unsigned int handle
, int bytes
);
168 void EDIT_HeapFree(HWND hwnd
, unsigned int handle
);
169 unsigned int EDIT_HeapSize(HWND hwnd
, unsigned int handle
);
170 void EDIT_SetHandleMsg(HWND hwnd
, WORD wParam
);
171 LONG
EDIT_SetTabStopsMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
172 void EDIT_CopyToClipboard(HWND hwnd
);
173 void EDIT_PasteMsg(HWND hwnd
);
174 void swap(int *a
, int *b
);
177 LONG
EditWndProc(HWND hwnd
, WORD uMsg
, WORD wParam
, LONG lParam
)
182 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
184 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
188 lResult
= es
->hDeletedText
;
191 case EM_EMPTYUNDOBUFFER
:
192 EDIT_ClearDeletedText(hwnd
);
196 fprintf(stdnimp
,"edit: EM_FMTLINES message received\n");
203 case EM_GETFIRSTVISIBLELINE
:
213 lResult
= EDIT_GetLineMsg(hwnd
, wParam
, lParam
);
218 case EM_GETLINECOUNT
:
220 lResult
= es
->wlines
;
226 lResult
= es
->TextChanged
;
229 case EM_GETPASSWORDCHAR
:
230 fprintf(stdnimp
,"edit: cannot process EM_GETPASSWORDCHAR message\n");
234 GetWindowRect(hwnd
, (LPRECT
)lParam
);
238 lResult
= EDIT_GetSelMsg(hwnd
);
241 case EM_GETWORDBREAKPROC
:
242 fprintf(stdnimp
,"edit: cannot process EM_GETWORDBREAKPROC message\n");
247 es
->MaxTextLen
= wParam
;
248 else if (IsMultiLine())
249 es
->MaxTextLen
= 65535;
251 es
->MaxTextLen
= 32767;
254 case EM_LINEFROMCHAR
:
255 lResult
= EDIT_LineFromCharMsg(hwnd
, wParam
);
260 lResult
= EDIT_LineIndexMsg(hwnd
, wParam
);
266 lResult
= EDIT_LineLengthMsg(hwnd
, wParam
);
270 fprintf(stdnimp
,"edit: cannot process EM_LINESCROLL message\n");
275 EDIT_ReplaceSel(hwnd
, lParam
);
276 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
282 EDIT_SetHandleMsg(hwnd
, wParam
);
283 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
288 es
->TextChanged
= wParam
;
291 case EM_SETPASSWORDCHAR
:
292 fprintf(stdnimp
,"edit: cannot process EM_SETPASSWORDCHAR message\n");
296 fprintf(stdnimp
,"edit: cannot process EM_SETREADONLY message\n");
301 fprintf(stdnimp
,"edit: cannot process EM_SETRECT(NP) message\n");
306 EDIT_SetSelMsg(hwnd
, wParam
, lParam
);
307 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
312 lResult
= EDIT_SetTabStopsMsg(hwnd
, wParam
, lParam
);
315 case EM_SETWORDBREAKPROC
:
316 fprintf(stdnimp
,"edit: cannot process EM_SETWORDBREAKPROC message\n");
321 lResult
= EDIT_UndoMsg(hwnd
);
322 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
327 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
330 EDIT_CharMsg(hwnd
, wParam
);
334 EDIT_CopyToClipboard(hwnd
);
339 lResult
= EDIT_CreateMsg(hwnd
, lParam
);
343 EDIT_CopyToClipboard(hwnd
);
344 EDIT_DeleteSel(hwnd
);
348 EDIT_HeapFree(hwnd
, es
->hTextPtrs
);
349 EDIT_HeapFree(hwnd
, es
->hCharWidths
);
350 EDIT_HeapFree(hwnd
, es
->hText
);
351 EDIT_HeapFree(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
355 InvalidateRect(hwnd
, NULL
, FALSE
);
359 textPtr
= EDIT_HeapAddr(hwnd
, es
->hText
);
360 if ((int)wParam
> (len
= strlen(textPtr
)))
362 strcpy((char *)lParam
, textPtr
);
363 lResult
= (DWORD
)len
;
369 case WM_GETTEXTLENGTH
:
370 textPtr
= EDIT_HeapAddr(hwnd
, es
->hText
);
371 lResult
= (DWORD
)strlen(textPtr
);
375 EDIT_HScrollMsg(hwnd
, wParam
, lParam
);
379 EDIT_KeyDownMsg(hwnd
, wParam
);
384 NOTIFY_PARENT(hwnd
, EN_KILLFOCUS
);
390 EDIT_LButtonDownMsg(hwnd
, wParam
, lParam
);
391 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
398 EDIT_StopMarking(hwnd
);
403 EDIT_MouseMoveMsg(hwnd
, wParam
, lParam
);
404 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
413 lResult
= EDIT_NCCreateMsg(hwnd
, lParam
);
425 CreateCaret(hwnd
, 0, 2, es
->txtht
);
426 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
428 NOTIFY_PARENT(hwnd
, EN_SETFOCUS
);
433 EDIT_SetFont(hwnd
, wParam
, lParam
);
434 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
439 dprintf_edit(stddeb
, "WM_SETREDRAW: hwnd=%d, wParam=%x\n",
445 EDIT_SetTextMsg(hwnd
, lParam
);
449 EDIT_SizeMsg(hwnd
, wParam
, lParam
);
454 EDIT_VScrollMsg(hwnd
, wParam
, lParam
);
458 lResult
= DefWindowProc(hwnd
, uMsg
, wParam
, lParam
);
466 /*********************************************************************
467 * WM_NCCREATE message function
470 long EDIT_NCCreateMsg(HWND hwnd
, LONG lParam
)
472 CREATESTRUCT
*createStruct
= (CREATESTRUCT
*)lParam
;
473 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
475 unsigned int *textPtrs
;
478 /* store pointer to local or global heap in window structure so that */
479 /* EDITSTATE structure itself can be stored on local heap */
480 if (HEAP_LocalFindHeap(createStruct
->hInstance
)!=NULL
)
481 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
482 &HEAP_LocalFindHeap(createStruct
->hInstance
)->free_list
;
485 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
486 GlobalLock(createStruct
->hInstance
);
487 /* GlobalUnlock(createStruct->hInstance); */
489 /* allocate space for state variable structure */
490 (HANDLE
)(*(wndPtr
->wExtra
)) = EDIT_HeapAlloc(hwnd
, sizeof(EDITSTATE
));
491 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
492 es
->hTextPtrs
= EDIT_HeapAlloc(hwnd
, sizeof(int));
493 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
494 es
->hCharWidths
= EDIT_HeapAlloc(hwnd
, 256 * sizeof(short));
496 /* --- text buffer */
497 es
->MaxTextLen
= MAXTEXTLEN
+ 1;
498 if (!(createStruct
->lpszName
))
500 es
->textlen
= EditBufLen(wndPtr
) + 1;
501 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
502 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
503 memset(text
, 0, es
->textlen
+ 2);
504 EDIT_ClearTextPointers(hwnd
);
508 if (strlen(createStruct
->lpszName
) < EditBufLen(wndPtr
))
510 es
->textlen
= EditBufLen(wndPtr
) + 1;
511 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
512 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
513 strcpy(text
, createStruct
->lpszName
);
514 *(text
+ es
->textlen
) = '\0';
518 es
->hText
= EDIT_HeapAlloc(hwnd
,
519 strlen(createStruct
->lpszName
) + 2);
520 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
521 strcpy(text
, createStruct
->lpszName
);
522 es
->textlen
= strlen(createStruct
->lpszName
) + 1;
524 *(text
+ es
->textlen
+ 1) = '\0';
525 EDIT_BuildTextPointers(hwnd
);
528 /* ES_AUTOVSCROLL and ES_AUTOHSCROLL are automatically applied if */
529 /* the corresponding WS_* style is set */
530 if (createStruct
->style
& WS_VSCROLL
)
531 wndPtr
->dwStyle
|= ES_AUTOVSCROLL
;
532 if (createStruct
->style
& WS_HSCROLL
)
533 wndPtr
->dwStyle
|= ES_AUTOHSCROLL
;
535 /* remove the WS_CAPTION style if it has been set - this is really a */
536 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
537 if (wndPtr
->dwStyle
& WS_BORDER
&& wndPtr
->dwStyle
& WS_DLGFRAME
)
538 wndPtr
->dwStyle
^= WS_DLGFRAME
;
544 /*********************************************************************
545 * WM_CREATE message function
548 long EDIT_CreateMsg(HWND hwnd
, LONG lParam
)
551 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
553 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
559 /* initialize state variable structure */
562 /* --- char width array */
563 /* only initialise chars <= 32 as X returns strange widths */
564 /* for other chars */
565 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
566 memset(charWidths
, 0, 256 * sizeof(short));
567 GetCharWidth(hdc
, 32, 254, &charWidths
[32]);
569 /* --- other structure variables */
570 GetTextMetrics(hdc
, &tm
);
571 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
573 es
->wtop
= es
->wleft
= 0;
574 es
->CurrCol
= es
->CurrLine
= 0;
575 es
->WndCol
= es
->WndRow
= 0;
576 es
->TextChanged
= FALSE
;
578 es
->SelBegLine
= es
->SelBegCol
= 0;
579 es
->SelEndLine
= es
->SelEndCol
= 0;
581 es
->hDeletedText
= 0;
582 es
->DeletedLength
= 0;
584 es
->hTabStops
= EDIT_HeapAlloc(hwnd
, sizeof(int));
586 /* allocate space for a line full of blanks to speed up */
588 es
->hBlankLine
= EDIT_HeapAlloc(hwnd
, (ClientWidth(wndPtr
) /
589 charWidths
[32]) + 2);
590 text
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
591 memset(text
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
593 /* set up text cursor for edit class */
594 CLASS_FindClassByName("EDIT", 0, &classPtr
);
595 classPtr
->wc
.hCursor
= LoadCursor(0, IDC_IBEAM
);
597 /* paint background on first WM_PAINT */
598 es
->PaintBkgd
= TRUE
;
600 ReleaseDC(hwnd
, hdc
);
605 /*********************************************************************
606 * EDIT_ClearTextPointers
608 * Clear and initialize text line pointer array.
611 void EDIT_ClearTextPointers(HWND hwnd
)
613 unsigned int *textPtrs
;
614 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
616 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
618 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
, sizeof(int));
619 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
624 /*********************************************************************
625 * EDIT_BuildTextPointers
627 * Build array of pointers to text lines.
630 #define INITLINES 100
632 void EDIT_BuildTextPointers(HWND hwnd
)
634 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
636 int incrs
= INITLINES
;
637 unsigned int off
, len
;
639 unsigned int *textPtrs
;
642 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
643 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
644 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
645 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
647 es
->textwidth
= es
->wlines
= 0;
650 /* advance through text buffer */
653 /* increase size of text pointer array */
654 if (incrs
== INITLINES
)
657 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
,
658 (es
->wlines
+ INITLINES
) * sizeof(int));
659 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
661 off
= (unsigned int)(cp
- text
); /* offset of beginning of line */
662 *(textPtrs
+ es
->wlines
) = off
;
667 /* advance through current line */
668 while (*cp
&& *cp
!= '\n')
670 len
+= EDIT_CharWidth(hwnd
, (BYTE
)*cp
, len
);
671 /* width of line in pixels */
674 es
->textwidth
= max(es
->textwidth
, len
);
676 cp
++; /* skip '\n' */
679 off
= (unsigned int)(cp
- text
);
680 *(textPtrs
+ es
->wlines
) = off
;
684 /*********************************************************************
685 * EDIT_ModTextPointers
687 * Modify text pointers from a specified position.
690 void EDIT_ModTextPointers(HWND hwnd
, int lineno
, int var
)
692 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
694 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
695 unsigned int *textPtrs
=
696 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
698 while (lineno
< es
->wlines
)
699 *(textPtrs
+ lineno
++) += var
;
703 /*********************************************************************
704 * WM_PAINT message function
707 void EDIT_PaintMsg(HWND hwnd
)
713 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
715 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
717 hdc
= BeginPaint(hwnd
, &ps
);
720 dprintf_edit(stddeb
,"WM_PAINT: rc=(%d,%d), (%d,%d)\n", rc
.left
, rc
.top
,
721 rc
.right
, rc
.bottom
);
724 FillWindow(GetParent(hwnd
), hwnd
, hdc
, CTLCOLOR_EDIT
);
726 for (y
= (rc
.top
/ es
->txtht
); y
<= (rc
.bottom
/ es
->txtht
); y
++)
728 if (y
< es
->wlines
- es
->wtop
)
729 EDIT_WriteTextLine(hwnd
, &rc
, y
+ es
->wtop
);
736 /*********************************************************************
739 * Get a copy of the text in the specified line.
742 HANDLE
EDIT_GetTextLine(HWND hwnd
, int selection
)
749 dprintf_edit(stddeb
,"GetTextLine %d\n", selection
);
750 cp
= cp1
= EDIT_TextLine(hwnd
, selection
);
751 /* advance through line */
752 while (*cp
&& *cp
!= '\r')
758 /* store selected line and return handle */
759 hLine
= EDIT_HeapAlloc(hwnd
, len
+ 6);
760 line
= (char *)EDIT_HeapAddr(hwnd
, hLine
);
761 memmove(line
, cp1
, len
);
767 /*********************************************************************
770 * Return a pointer to the text in the specified line.
773 char *EDIT_TextLine(HWND hwnd
, int sel
)
775 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
777 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
778 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
779 unsigned int *textPtrs
=
780 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
782 if(sel
>es
->wlines
)return NULL
;
783 return (text
+ *(textPtrs
+ sel
));
787 /*********************************************************************
790 * Return length of string _str_ of length _len_ characters in pixels.
791 * The current column offset in pixels _pcol_ is required to calculate
792 * the width of a tab.
795 int EDIT_StrLength(HWND hwnd
, unsigned char *str
, int len
, int pcol
)
799 for (i
= 0; i
< len
; i
++)
800 plen
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(str
+ i
)), pcol
+ plen
);
802 dprintf_edit(stddeb
,"EDIT_StrLength: returning %d\n", plen
);
807 /*********************************************************************
810 * Return length of line _num_ in characters.
813 int EDIT_LineLength(HWND hwnd
, int num
)
815 char *cp
= EDIT_TextLine(hwnd
, num
);
819 cp1
= strchr(cp
, '\r');
820 return cp1
? (int)(cp1
- cp
) : strlen(cp
);
824 /*********************************************************************
827 * Write the line of text at offset _y_ in text buffer to a window.
830 void EDIT_WriteTextLine(HWND hwnd
, RECT
*rect
, int y
)
837 int sbl
, sel
, sbc
, sec
;
839 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
841 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
843 /* initialize rectangle if NULL, else copy */
847 GetClientRect(hwnd
, &rc
);
849 dprintf_edit(stddeb
,"WriteTextLine %d\n", y
);
851 /* make sure y is inside the window */
852 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
854 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is not a displayed line\n", y
);
858 /* make sure rectangle is within window */
859 if (rc
.left
>= ClientWidth(wndPtr
) - 1)
861 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.left (%d) is greater than right edge\n",
867 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.right (%d) is less than left edge\n",
871 if (y
- es
->wtop
< (rc
.top
/ es
->txtht
) ||
872 y
- es
->wtop
> (rc
.bottom
/ es
->txtht
))
874 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is outside window\n", y
);
878 /* get the text and length of line */
879 if ((hLine
= EDIT_GetTextLine(hwnd
, y
)) == 0)
881 lp
= (unsigned char *)EDIT_HeapAddr(hwnd
, hLine
);
882 lnlen
= EDIT_StrLength(hwnd
, lp
, strlen(lp
), 0);
885 /* build the line to display */
886 if (lnlen
< es
->wleft
)
894 lnlen
= lnlen1
- off
;
895 len
= min(lnlen
, rc
.right
- rc
.left
);
900 sbl
= es
->SelBegLine
;
901 sel
= es
->SelEndLine
;
905 /* put lowest marker first */
911 if (sbl
== sel
&& sbc
> sec
)
914 if (y
< sbl
|| y
> sel
)
915 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
917 else if (y
> sbl
&& y
< sel
)
918 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
922 col
= EDIT_StrLength(hwnd
, lp
, sbc
, 0);
923 if (col
> (es
->wleft
+ rc
.left
))
925 len
= min(col
- off
, rc
.right
- off
);
926 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
927 rc
.left
, &rc
, FALSE
, FALSE
);
932 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
933 if (col
< (es
->wleft
+ rc
.right
))
935 len
= min(col
- off
, rc
.right
- off
);
936 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
937 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
939 len
= min(lnlen
- off
, rc
.right
- off
);
940 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
941 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
945 len
= min(lnlen
- off
, rc
.right
- off
);
946 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
947 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
952 len
= min(lnlen
- off
, rc
.right
- off
);
953 if (col
< (es
->wleft
+ rc
.right
))
954 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
955 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
960 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
961 if (col
< (es
->wleft
+ rc
.right
))
963 len
= min(col
- off
, rc
.right
- off
);
964 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
965 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
967 len
= min(lnlen
- off
, rc
.right
- off
);
968 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
969 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
974 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
977 EDIT_HeapFree(hwnd
, hLine
);
981 /*********************************************************************
984 * Write text to a window
986 * off - offset in text line (in pixels)
987 * len - length from off (in pixels)
988 * row - line in window
989 * col - column in window
990 * rc - rectangle in which to display line
991 * blank - blank remainder of line?
992 * reverse - reverse color of line?
995 void EDIT_WriteText(HWND hwnd
, char *lp
, int off
, int len
, int row
,
996 int col
, RECT
*rc
, BOOL blank
, BOOL reverse
)
1000 char *str
, *cp
, *cp1
;
1001 int diff
, num_spaces
, tabwidth
, scol
;
1003 COLORREF oldTextColor
, oldBkgdColor
;
1005 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1007 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1008 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1009 char *blanks
= (char *)EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1011 dprintf_edit(stddeb
,"EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp
, off
, len
, row
, col
, reverse
);
1014 hStr
= EDIT_GetStr(hwnd
, lp
, off
, len
, &diff
);
1015 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1016 hrgnClip
= CreateRectRgnIndirect(rc
);
1017 SelectClipRgn(hdc
, hrgnClip
);
1020 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
1022 SendMessage(GetParent(hwnd
), WM_CTLCOLOR
, (WORD
)hdc
,
1023 MAKELPARAM(hwnd
, CTLCOLOR_EDIT
));
1027 oldBkgdColor
= GetBkColor(hdc
);
1028 oldTextColor
= GetTextColor(hdc
);
1029 SetBkColor(hdc
, oldTextColor
);
1030 SetTextColor(hdc
, oldBkgdColor
);
1033 if (strlen(blanks
) < (ClientWidth(wndPtr
) / charWidths
[32]) + 2)
1035 es
->hBlankLine
= EDIT_HeapReAlloc(hwnd
, es
->hBlankLine
,
1036 (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1037 blanks
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1038 memset(blanks
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1041 if (!(cp
= strchr(str
, VK_TAB
)))
1042 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, strlen(str
));
1045 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, (int)(cp
- str
));
1046 scol
= EDIT_StrLength(hwnd
, str
, (int)(cp
- str
), 0);
1047 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1048 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1049 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1053 while ((cp1
= strchr(cp
, VK_TAB
)))
1055 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, (int)(cp1
- cp
));
1056 scol
+= EDIT_StrLength(hwnd
, cp
, (int)(cp1
- cp
), scol
);
1057 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1058 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1059 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1064 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, strlen(cp
));
1069 SetBkColor(hdc
, oldBkgdColor
);
1070 SetTextColor(hdc
, oldTextColor
);
1073 /* blank out remainder of line if appropriate */
1076 if ((rc
->right
- col
) > len
)
1078 num_spaces
= (rc
->right
- col
- len
) / charWidths
[32];
1079 TextOut(hdc
, col
+ len
, row
* es
->txtht
, blanks
, num_spaces
);
1084 SelectObject(hdc
, (HANDLE
)oldfont
);
1086 EDIT_HeapFree(hwnd
, hStr
);
1087 ReleaseDC(hwnd
, hdc
);
1091 /*********************************************************************
1094 * Return sub-string starting at pixel _off_ of length _len_ pixels.
1095 * If _off_ is part way through a character, the negative offset of
1096 * the beginning of the character is returned in _diff_, else _diff_
1100 HANDLE
EDIT_GetStr(HWND hwnd
, char *lp
, int off
, int len
, int *diff
)
1104 int ch
= 0, i
= 0, j
, s_i
=0;
1107 dprintf_edit(stddeb
,"EDIT_GetStr lp='%s' off=%d len=%d\n", lp
, off
, len
);
1109 if (off
< 0) off
= 0;
1113 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1116 /* if stepped past _off_, go back a character */
1124 while (i
< len
+ off
)
1126 if (*(lp
+ ch
) == '\r' || *(lp
+ ch
) == '\n')
1128 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1132 hStr
= EDIT_HeapAlloc(hwnd
, ch
- ch1
+ 3);
1133 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1134 for (i
= ch1
, j
= 0; i
< ch
; i
++, j
++)
1137 dprintf_edit(stddeb
,"EDIT_GetStr: returning %s\n", str
);
1142 /*********************************************************************
1143 * WM_CHAR message function
1146 void EDIT_CharMsg(HWND hwnd
, WORD wParam
)
1148 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1150 dprintf_edit(stddeb
,"EDIT_CharMsg: wParam=%c\n", (char)wParam
);
1159 EDIT_KeyTyped(hwnd
, wParam
);
1165 EDIT_KeyTyped(hwnd
, wParam
);
1169 if (wParam
>= 20 && wParam
<= 126)
1170 EDIT_KeyTyped(hwnd
, wParam
);
1176 /*********************************************************************
1179 * Process keystrokes that produce displayable characters.
1182 void EDIT_KeyTyped(HWND hwnd
, short ch
)
1184 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1186 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1187 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1188 char *currchar
= CurrChar
;
1190 BOOL FullPaint
= FALSE
;
1192 dprintf_edit(stddeb
,"EDIT_KeyTyped: ch=%c\n", (char)ch
);
1194 /* delete selected text (if any) */
1196 EDIT_DeleteSel(hwnd
);
1198 /* test for typing at end of maximum buffer size */
1199 if (currchar
== text
+ es
->MaxTextLen
)
1201 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1205 if (*currchar
== '\0' && IsMultiLine())
1207 /* insert a newline at end of text */
1209 *(currchar
+ 1) = '\n';
1210 *(currchar
+ 2) = '\0';
1211 EDIT_BuildTextPointers(hwnd
);
1214 /* insert the typed character */
1215 if (text
[es
->textlen
- 1] != '\0')
1217 /* current text buffer is full */
1218 if (es
->textlen
== es
->MaxTextLen
)
1220 /* text buffer is at maximum size */
1221 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1225 /* increase the text buffer size */
1226 es
->textlen
+= GROWLENGTH
;
1227 /* but not above maximum size */
1228 if (es
->textlen
> es
->MaxTextLen
)
1229 es
->textlen
= es
->MaxTextLen
;
1230 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ 2);
1232 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1233 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1234 text
[es
->textlen
- 1] = '\0';
1235 currchar
= CurrChar
;
1237 /* make space for new character and put char in buffer */
1240 memmove(currchar
+ 2, currchar
, strlen(currchar
) + 1);
1242 *(currchar
+ 1) = '\n';
1243 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, 2);
1247 memmove(currchar
+ 1, currchar
, strlen(currchar
) + 1);
1249 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, 1);
1251 es
->TextChanged
= TRUE
;
1252 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1254 /* re-adjust textwidth, if necessary, and redraw line */
1256 if (IsMultiLine() && es
->wlines
> 1)
1258 es
->textwidth
= max(es
->textwidth
,
1259 EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
1260 (int)(EDIT_TextLine(hwnd
, es
->CurrLine
+ 1) -
1261 EDIT_TextLine(hwnd
, es
->CurrLine
)), 0));
1264 es
->textwidth
= max(es
->textwidth
,
1265 EDIT_StrLength(hwnd
, text
, strlen(text
), 0));
1266 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ es
->WndRow
);
1273 EDIT_BuildTextPointers(hwnd
);
1277 /* invalidate rest of window */
1278 GetClientRect(hwnd
, &rc
);
1280 rc
.top
= es
->WndRow
* es
->txtht
;
1281 InvalidateRect(hwnd
, &rc
, FALSE
);
1283 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1286 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1290 /* test end of window */
1291 if (es
->WndCol
>= ClientWidth(wndPtr
) -
1292 EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
))
1294 /* TODO:- Word wrap to be handled here */
1296 /* if (!(currchar == text + es->MaxTextLen - 2)) */
1297 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1299 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
);
1301 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1303 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1307 /*********************************************************************
1310 * Return the width of the given character in pixels.
1311 * The current column offset in pixels _pcol_ is required to calculate
1312 * the width of a tab.
1315 int EDIT_CharWidth(HWND hwnd
, short ch
, int pcol
)
1317 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1319 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1320 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1323 return (charWidths
[ch
]);
1325 return (EDIT_GetNextTabStop(hwnd
, pcol
) - pcol
);
1329 /*********************************************************************
1330 * EDIT_GetNextTabStop
1332 * Return the next tab stop beyond _pcol_.
1335 int EDIT_GetNextTabStop(HWND hwnd
, int pcol
)
1338 int baseUnitWidth
= LOWORD(GetDialogBaseUnits());
1339 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1341 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1342 unsigned short *tabstops
= EDIT_HeapAddr(hwnd
, es
->hTabStops
);
1344 if (es
->NumTabStops
== 0)
1345 return ROUNDUP(pcol
, 8 * baseUnitWidth
);
1346 else if (es
->NumTabStops
== 1)
1347 return ROUNDUP(pcol
, *tabstops
* baseUnitWidth
/ 4);
1350 for (i
= 0; i
< es
->NumTabStops
; i
++)
1352 if (*(tabstops
+ i
) * baseUnitWidth
/ 4 >= pcol
)
1353 return (*(tabstops
+ i
) * baseUnitWidth
/ 4);
1360 /*********************************************************************
1363 * Cursor right key: move right one character position.
1366 void EDIT_Forward(HWND hwnd
)
1368 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1370 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1372 if (*CurrChar
== '\0')
1375 if (*CurrChar
== '\r')
1378 EDIT_Downward(hwnd
);
1382 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1384 if (es
->WndCol
>= ClientWidth(wndPtr
))
1385 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1391 /*********************************************************************
1394 * Cursor down key: move down one line.
1397 void EDIT_Downward(HWND hwnd
)
1399 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1401 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1403 dprintf_edit(stddeb
,"EDIT_Downward: WndRow=%d, wtop=%d, wlines=%d\n",
1404 es
->WndRow
, es
->wtop
, es
->wlines
);
1406 if (IsMultiLine() && (es
->WndRow
+ es
->wtop
+ 1 < es
->wlines
))
1409 if (es
->WndRow
== ClientHeight(wndPtr
, es
) - 1)
1412 EDIT_KeyVScrollLine(hwnd
, SB_LINEDOWN
);
1416 EDIT_StickEnd(hwnd
);
1421 /*********************************************************************
1424 * Cursor up key: move up one line.
1427 void EDIT_Upward(HWND hwnd
)
1429 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1431 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1433 if (IsMultiLine() && es
->CurrLine
!= 0)
1436 if (es
->WndRow
== 0)
1439 EDIT_KeyVScrollLine(hwnd
, SB_LINEUP
);
1443 EDIT_StickEnd(hwnd
);
1448 /*********************************************************************
1451 * Cursor left key: move left one character position.
1454 void EDIT_Backward(HWND hwnd
)
1456 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1458 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1463 if (*CurrChar
== VK_TAB
)
1464 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
),
1465 EDIT_StrLength(hwnd
,
1466 EDIT_TextLine(hwnd
, es
->CurrLine
),
1469 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), 0);
1471 EDIT_KeyHScroll(hwnd
, SB_LINEUP
);
1473 else if (IsMultiLine() && es
->CurrLine
!= 0)
1481 /*********************************************************************
1484 * End key: move to end of line.
1487 void EDIT_End(HWND hwnd
)
1489 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1491 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1493 while (*CurrChar
&& *CurrChar
!= '\r')
1495 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1499 if (es
->WndCol
>= ClientWidth(wndPtr
))
1501 es
->wleft
= es
->WndCol
- ClientWidth(wndPtr
) + HSCROLLDIM
;
1502 es
->WndCol
-= es
->wleft
;
1503 InvalidateRect(hwnd
, NULL
, FALSE
);
1509 /*********************************************************************
1512 * Home key: move to beginning of line.
1515 void EDIT_Home(HWND hwnd
)
1517 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1519 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1521 es
->CurrCol
= es
->WndCol
= 0;
1525 InvalidateRect(hwnd
, NULL
, FALSE
);
1531 /*********************************************************************
1534 * Stick the cursor to the end of the line.
1537 void EDIT_StickEnd(HWND hwnd
)
1539 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1541 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1542 int len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
1543 char *cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
1546 es
->CurrCol
= min(len
, es
->CurrCol
);
1547 es
->WndCol
= min(EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
, es
->WndCol
);
1548 currpel
= EDIT_StrLength(hwnd
, cp
, es
->CurrCol
, 0);
1550 if (es
->wleft
> currpel
)
1552 es
->wleft
= max(0, currpel
- 20);
1553 es
->WndCol
= currpel
- es
->wleft
;
1556 else if (currpel
- es
->wleft
>= ClientWidth(wndPtr
))
1558 es
->wleft
= currpel
- (ClientWidth(wndPtr
) - 5);
1559 es
->WndCol
= currpel
- es
->wleft
;
1565 /*********************************************************************
1566 * WM_KEYDOWN message function
1569 void EDIT_KeyDownMsg(HWND hwnd
, WORD wParam
)
1571 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1573 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1575 dprintf_edit(stddeb
,"EDIT_KeyDownMsg: key=%x\n", wParam
);
1582 EDIT_ClearSel(hwnd
);
1586 EDIT_Backward(hwnd
);
1591 EDIT_ClearSel(hwnd
);
1593 EDIT_Downward(hwnd
);
1600 EDIT_ClearSel(hwnd
);
1606 EDIT_ClearSel(hwnd
);
1607 EDIT_Backward(hwnd
);
1612 EDIT_ClearSel(hwnd
);
1618 EDIT_ClearSel(hwnd
);
1626 EDIT_ClearSel(hwnd
);
1627 EDIT_KeyVScrollPage(hwnd
, SB_PAGEUP
);
1635 EDIT_ClearSel(hwnd
);
1636 EDIT_KeyVScrollPage(hwnd
, SB_PAGEDOWN
);
1642 EDIT_DeleteSel(hwnd
);
1645 if (es
->CurrCol
== 0 && es
->CurrLine
== 0)
1647 EDIT_Backward(hwnd
);
1654 EDIT_DeleteSel(hwnd
);
1660 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1665 /*********************************************************************
1668 * Scroll text horizontally using cursor keys.
1671 void EDIT_KeyHScroll(HWND hwnd
, WORD opt
)
1674 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1676 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1678 if (opt
== SB_LINEDOWN
)
1680 es
->wleft
+= HSCROLLDIM
;
1681 es
->WndCol
-= HSCROLLDIM
;
1687 if (es
->wleft
- HSCROLLDIM
< 0)
1689 es
->WndCol
+= es
->wleft
;
1694 es
->wleft
-= HSCROLLDIM
;
1695 es
->WndCol
+= HSCROLLDIM
;
1699 InvalidateRect(hwnd
, NULL
, FALSE
);
1704 hscrollpos
= EDIT_ComputeHScrollPos(hwnd
);
1705 SetScrollPos(hwnd
, SB_HORZ
, hscrollpos
, TRUE
);
1710 /*********************************************************************
1711 * EDIT_KeyVScrollLine
1713 * Scroll text vertically by one line using keyboard.
1716 void EDIT_KeyVScrollLine(HWND hwnd
, WORD opt
)
1720 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1722 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1727 if (opt
== SB_LINEDOWN
)
1729 /* move down one line */
1730 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
1736 /* move up one line */
1742 if (IsWindowVisible(hwnd
))
1744 /* adjust client bottom to nearest whole line */
1745 GetClientRect(hwnd
, &rc
);
1746 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
1748 if (opt
== SB_LINEUP
)
1750 /* move up one line (scroll window down) */
1751 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
1752 /* write top line */
1753 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
1758 /* move down one line (scroll window up) */
1759 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
1760 /* write bottom line */
1761 y
= (((rc
.bottom
- rc
.top
) / es
->txtht
) - 1);
1762 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
1767 /* reset the vertical scroll bar */
1770 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1771 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1776 /*********************************************************************
1777 * EDIT_KeyVScrollPage
1779 * Scroll text vertically by one page using keyboard.
1782 void EDIT_KeyVScrollPage(HWND hwnd
, WORD opt
)
1785 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1787 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1791 if (opt
== SB_PAGEUP
)
1794 es
->wtop
-= ClientHeight(wndPtr
, es
);
1798 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1800 es
->wtop
+= ClientHeight(wndPtr
, es
);
1801 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
1802 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1808 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
1809 EDIT_StickEnd(hwnd
);
1810 InvalidateRect(hwnd
, NULL
, TRUE
);
1813 /* reset the vertical scroll bar */
1816 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1817 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1823 /*********************************************************************
1824 * EDIT_KeyVScrollDoc
1826 * Scroll text to top and bottom of document using keyboard.
1829 void EDIT_KeyVScrollDoc(HWND hwnd
, WORD opt
)
1832 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1834 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1840 es
->wtop
= es
->wleft
= 0;
1841 else if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1843 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1847 es
->CurrLine
= es
->wlines
;
1848 es
->WndRow
= es
->wlines
- es
->wtop
;
1850 InvalidateRect(hwnd
, NULL
, TRUE
);
1853 /* reset the vertical scroll bar */
1856 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1857 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1862 /*********************************************************************
1863 * EDIT_ComputeVScrollPos
1865 * Compute the vertical scroll bar position from the window
1866 * position and text width.
1869 int EDIT_ComputeVScrollPos(HWND hwnd
)
1872 short minpos
, maxpos
;
1873 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1875 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1877 GetScrollRange(hwnd
, SB_VERT
, &minpos
, &maxpos
);
1879 if (es
->wlines
> ClientHeight(wndPtr
, es
))
1880 vscrollpos
= (double)(es
->wtop
) / (double)(es
->wlines
-
1881 ClientHeight(wndPtr
, es
)) * (maxpos
- minpos
);
1883 vscrollpos
= minpos
;
1889 /*********************************************************************
1890 * EDIT_ComputeHScrollPos
1892 * Compute the horizontal scroll bar position from the window
1893 * position and text width.
1896 int EDIT_ComputeHScrollPos(HWND hwnd
)
1899 short minpos
, maxpos
;
1900 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1902 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1904 GetScrollRange(hwnd
, SB_HORZ
, &minpos
, &maxpos
);
1906 if (es
->textwidth
> ClientWidth(wndPtr
))
1907 hscrollpos
= (double)(es
->wleft
) / (double)(es
->textwidth
-
1908 ClientWidth(wndPtr
)) * (maxpos
- minpos
);
1910 hscrollpos
= minpos
;
1916 /*********************************************************************
1919 * Delete character to right of cursor.
1922 void EDIT_DelKey(HWND hwnd
)
1925 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1927 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1928 char *currchar
= CurrChar
;
1929 BOOL repaint
= *currchar
== '\n';
1931 if (IsMultiLine() && *currchar
== '\n' && *(currchar
+ 1) == '\0')
1933 strcpy(currchar
, currchar
+ 1);
1934 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1938 EDIT_BuildTextPointers(hwnd
);
1939 GetClientRect(hwnd
, &rc
);
1940 rc
.top
= es
->WndRow
* es
->txtht
;
1941 InvalidateRect(hwnd
, &rc
, FALSE
);
1946 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, -1);
1947 EDIT_WriteTextLine(hwnd
, NULL
, es
->WndRow
+ es
->wtop
);
1950 es
->TextChanged
= TRUE
;
1951 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1954 /*********************************************************************
1955 * WM_VSCROLL message function
1958 void EDIT_VScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
1960 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1962 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1972 EDIT_VScrollLine(hwnd
, wParam
);
1977 EDIT_VScrollPage(hwnd
, wParam
);
1982 SetCaretPos(es
->WndCol
, es
->WndRow
);
1987 /*********************************************************************
1990 * Scroll text vertically by one line using scrollbars.
1993 void EDIT_VScrollLine(HWND hwnd
, WORD opt
)
1997 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1999 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2001 dprintf_edit(stddeb
,"EDIT_VScrollLine: direction=%d\n", opt
);
2003 if (opt
== SB_LINEDOWN
)
2005 /* move down one line */
2006 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
2012 /* move up one line */
2018 if (IsWindowVisible(hwnd
))
2020 /* adjust client bottom to nearest whole line */
2021 GetClientRect(hwnd
, &rc
);
2022 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
2024 if (opt
== SB_LINEUP
)
2026 /* move up one line (scroll window down) */
2027 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
2028 /* write top line */
2029 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
2034 /* move down one line (scroll window up) */
2035 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
2036 /* write bottom line */
2037 y
= ((rc
.bottom
- rc
.top
/ es
->txtht
) - 1);
2038 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
2045 /*********************************************************************
2048 * Scroll text vertically by one page using keyboard.
2051 void EDIT_VScrollPage(HWND hwnd
, WORD opt
)
2054 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2056 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2058 if (opt
== SB_PAGEUP
)
2061 es
->wtop
-= ClientHeight(wndPtr
, es
);
2065 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
2067 es
->wtop
+= ClientHeight(wndPtr
, es
);
2068 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
2069 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
2075 InvalidateRect(hwnd
, NULL
, TRUE
);
2078 /* reset the vertical scroll bar */
2081 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
2082 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
2087 /*********************************************************************
2088 * WM_HSCROLL message function
2091 void EDIT_HScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2093 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2095 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2103 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
2110 /*********************************************************************
2111 * WM_SIZE message function
2114 void EDIT_SizeMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2116 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2118 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2120 if (wParam
!= SIZE_MAXIMIZED
&& wParam
!= SIZE_RESTORED
) return;
2122 InvalidateRect(hwnd
, NULL
, TRUE
);
2123 es
->PaintBkgd
= TRUE
;
2128 /*********************************************************************
2129 * WM_LBUTTONDOWN message function
2132 void EDIT_LButtonDownMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2137 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2139 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2142 EDIT_ClearSel(hwnd
);
2144 es
->WndRow
= HIWORD(lParam
) / es
->txtht
;
2145 if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2148 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2153 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2155 cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
2156 len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
2157 es
->WndCol
= LOWORD(lParam
);
2158 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
|| end
)
2159 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
;
2160 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2163 ButtonRow
= es
->CurrLine
;
2164 ButtonCol
= es
->CurrCol
;
2168 /*********************************************************************
2169 * WM_MOUSEMOVE message function
2172 void EDIT_MouseMoveMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2174 if (wParam
!= MK_LBUTTON
)
2179 EDIT_SetAnchor(hwnd
, ButtonRow
, ButtonCol
);
2185 EDIT_ExtendSel(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
2189 /*********************************************************************
2192 * Convert a pixel offset in the given row to a character offset,
2193 * adjusting the pixel offset to the nearest whole character if
2197 int EDIT_PixelToChar(HWND hwnd
, int row
, int *pixel
)
2199 int ch
= 0, i
= 0, s_i
= 0;
2202 dprintf_edit(stddeb
,"EDIT_PixelToChar: row=%d, pixel=%d\n", row
, *pixel
);
2204 text
= EDIT_TextLine(hwnd
, row
);
2208 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(text
+ ch
)), i
);
2212 /* if stepped past _pixel_, go back a character */
2223 /*********************************************************************
2224 * WM_SETTEXT message function
2227 LONG
EDIT_SetTextMsg(HWND hwnd
, LONG lParam
)
2231 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2233 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2235 if (strlen((char *)lParam
) <= es
->MaxTextLen
)
2237 len
= ( lParam
? strlen((char *)lParam
) : 0 );
2238 EDIT_ClearText(hwnd
);
2240 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, len
+ 3);
2241 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2243 strcpy(text
, (char *)lParam
);
2245 text
[len
+ 1] = '\0';
2246 text
[len
+ 2] = '\0';
2247 EDIT_BuildTextPointers(hwnd
);
2248 InvalidateRect(hwnd
, NULL
, TRUE
);
2249 es
->PaintBkgd
= TRUE
;
2250 es
->TextChanged
= TRUE
;
2258 /*********************************************************************
2261 * Clear text from text buffer.
2264 void EDIT_ClearText(HWND hwnd
)
2266 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2268 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2269 unsigned int blen
= EditBufLen(wndPtr
) + 2;
2272 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, blen
);
2273 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2274 memset(text
, 0, blen
);
2277 es
->CurrLine
= es
->CurrCol
= 0;
2278 es
->WndRow
= es
->WndCol
= 0;
2279 es
->wleft
= es
->wtop
= 0;
2281 es
->TextChanged
= FALSE
;
2282 EDIT_ClearTextPointers(hwnd
);
2286 /*********************************************************************
2287 * EM_SETSEL message function
2290 void EDIT_SetSelMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2293 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2295 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2297 so
= LOWORD(lParam
);
2298 eo
= HIWORD(lParam
);
2300 if (so
== -1) /* if so == -1, clear selection */
2302 EDIT_ClearSel(hwnd
);
2306 if (so
== eo
) /* if so == eo, set caret only */
2308 EDIT_GetLineCol(hwnd
, so
, &(es
->CurrLine
), &(es
->CurrCol
));
2309 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2313 if (es
->WndRow
< 0 || es
->WndRow
> ClientHeight(wndPtr
, es
))
2315 es
->wtop
= es
->CurrLine
;
2318 es
->WndCol
= EDIT_StrLength(hwnd
,
2319 EDIT_TextLine(hwnd
, es
->CurrLine
),
2320 es
->CurrCol
, 0) - es
->wleft
;
2321 if (es
->WndCol
> ClientWidth(wndPtr
))
2323 es
->wleft
= es
->WndCol
;
2326 else if (es
->WndCol
< 0)
2328 es
->wleft
+= es
->WndCol
;
2333 else /* otherwise set selection */
2338 EDIT_GetLineCol(hwnd
, so
, &(es
->SelBegLine
), &(es
->SelBegCol
));
2339 EDIT_GetLineCol(hwnd
, eo
, &(es
->SelEndLine
), &(es
->SelEndCol
));
2340 es
->CurrLine
= es
->SelEndLine
;
2341 es
->CurrCol
= es
->SelEndCol
;
2342 es
->WndRow
= es
->SelEndLine
- es
->wtop
;
2344 if (!wParam
) /* don't suppress scrolling of text */
2348 es
->wtop
= es
->SelEndLine
;
2351 else if (es
->WndRow
> ClientHeight(wndPtr
, es
))
2353 es
->wtop
+= es
->WndRow
- ClientHeight(wndPtr
, es
);
2354 es
->WndRow
= ClientHeight(wndPtr
, es
);
2356 es
->WndCol
= EDIT_StrLength(hwnd
,
2357 EDIT_TextLine(hwnd
, es
->SelEndLine
),
2358 es
->SelEndCol
, 0) - es
->wleft
;
2359 if (es
->WndCol
> ClientWidth(wndPtr
))
2361 es
->wleft
+= es
->WndCol
- ClientWidth(wndPtr
);
2362 es
->WndCol
= ClientWidth(wndPtr
);
2364 else if (es
->WndCol
< 0)
2366 es
->wleft
+= es
->WndCol
;
2371 InvalidateRect(hwnd
, NULL
, TRUE
);
2377 /*********************************************************************
2380 * Return line and column in text buffer from character offset.
2383 void EDIT_GetLineCol(HWND hwnd
, int off
, int *line
, int *col
)
2387 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2389 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2390 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2391 unsigned int *textPtrs
=
2392 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2394 /* check for (0,0) */
2402 if (off
> strlen(text
)) off
= strlen(text
);
2404 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2406 cp
= text
+ *(textPtrs
+ lineno
);
2407 if (off
== (int)(cp
- text
))
2413 if (off
< (int)(cp
- text
))
2418 *col
= off
- (int)(cp1
- text
);
2420 if (*(text
+ *col
) == '\0')
2426 /*********************************************************************
2429 * Delete the current selected text (if any)
2432 void EDIT_DeleteSel(HWND hwnd
)
2436 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2438 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2442 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
2443 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
2444 len
= (int)(bel
- bbl
);
2445 EDIT_SaveDeletedText(hwnd
, bbl
, len
, es
->SelBegLine
, es
->SelBegCol
);
2446 es
->TextChanged
= TRUE
;
2449 es
->CurrLine
= es
->SelBegLine
;
2450 es
->CurrCol
= es
->SelBegCol
;
2451 es
->WndRow
= es
->SelBegLine
- es
->wtop
;
2454 es
->wtop
= es
->SelBegLine
;
2457 es
->WndCol
= EDIT_StrLength(hwnd
, bbl
- es
->SelBegCol
,
2458 es
->SelBegCol
, 0) - es
->wleft
;
2460 EDIT_BuildTextPointers(hwnd
);
2461 es
->PaintBkgd
= TRUE
;
2462 EDIT_ClearSel(hwnd
);
2467 /*********************************************************************
2470 * Clear the current selection.
2473 void EDIT_ClearSel(HWND hwnd
)
2475 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2477 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2479 es
->SelBegLine
= es
->SelBegCol
= 0;
2480 es
->SelEndLine
= es
->SelEndCol
= 0;
2482 InvalidateRect(hwnd
, NULL
, TRUE
);
2487 /*********************************************************************
2488 * EDIT_TextLineNumber
2490 * Return the line number in the text buffer of the supplied
2491 * character pointer.
2494 int EDIT_TextLineNumber(HWND hwnd
, char *lp
)
2498 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2500 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2501 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2502 unsigned int *textPtrs
=
2503 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2505 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2507 cp
= text
+ *(textPtrs
+ lineno
);
2517 /*********************************************************************
2520 * Set down anchor for text marking.
2523 void EDIT_SetAnchor(HWND hwnd
, int row
, int col
)
2526 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2528 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2532 EDIT_ClearSel(hwnd
);
2533 es
->SelBegLine
= es
->SelEndLine
= row
;
2534 es
->SelBegCol
= es
->SelEndCol
= col
;
2537 InvalidateRect(hwnd
, NULL
, FALSE
);
2543 /*********************************************************************
2546 * Extend selection to the given screen co-ordinates.
2549 void EDIT_ExtendSel(HWND hwnd
, int x
, int y
)
2551 int bbl
, bel
, bbc
, bec
;
2555 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2557 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2559 dprintf_edit(stddeb
,"EDIT_ExtendSel: x=%d, y=%d\n", x
, y
);
2561 bbl
= es
->SelEndLine
;
2562 bbc
= es
->SelEndCol
;
2563 line
= es
->wtop
+ y
/ es
->txtht
;
2564 if (line
> es
->wlines
)
2566 cp
= EDIT_TextLine(hwnd
, line
);
2567 len
= EDIT_LineLength(hwnd
, line
);
2569 es
->WndRow
= y
/ es
->txtht
;
2570 if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2573 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2578 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2579 es
->SelEndLine
= es
->CurrLine
;
2582 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
|| end
)
2583 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
;
2584 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2585 es
->SelEndCol
= es
->CurrCol
;
2587 bel
= es
->SelEndLine
;
2588 bec
= es
->SelEndCol
;
2590 /* return if no new characters to mark */
2591 if (bbl
== bel
&& bbc
== bec
)
2594 /* put lowest marker first */
2600 if (bbl
== bel
&& bbc
> bec
)
2603 for (y
= bbl
; y
<= bel
; y
++)
2605 if (y
== bbl
&& y
== bel
)
2606 EDIT_WriteSel(hwnd
, y
, bbc
, bec
);
2608 EDIT_WriteSel(hwnd
, y
, bbc
, -1);
2610 EDIT_WriteSel(hwnd
, y
, 0, bec
);
2612 EDIT_WriteSel(hwnd
, y
, 0, -1);
2617 /*********************************************************************
2620 * Display selection by reversing pixels in selected text.
2621 * If end == -1, selection applies to end of line.
2624 void EDIT_WriteSel(HWND hwnd
, int y
, int start
, int end
)
2630 HBRUSH hbrush
, holdbrush
;
2632 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2634 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2636 dprintf_edit(stddeb
,"EDIT_WriteSel: y=%d start=%d end=%d\n", y
, start
,end
);
2637 GetClientRect(hwnd
, &rc
);
2639 /* make sure y is within the window */
2640 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
2643 /* get pointer to text */
2644 cp
= EDIT_TextLine(hwnd
, y
);
2646 /* get length of line if end == -1 */
2648 end
= EDIT_LineLength(hwnd
, y
);
2650 /* For some reason Rectangle, when called with R2_XORPEN filling,
2651 * appears to leave a 2 pixel gap between characters and between
2652 * lines. I have kludged this by adding on two pixels to ecol and
2653 * to the line height in the call to Rectangle.
2655 scol
= EDIT_StrLength(hwnd
, cp
, start
, 0);
2656 if (scol
> rc
.right
) return;
2657 if (scol
< rc
.left
) scol
= rc
.left
;
2658 ecol
= EDIT_StrLength(hwnd
, cp
, end
, 0) + 2; /* ??? */
2659 if (ecol
< rc
.left
) return;
2660 if (ecol
> rc
.right
) ecol
= rc
.right
;
2663 hbrush
= GetStockObject(BLACK_BRUSH
);
2664 holdbrush
= (HBRUSH
)SelectObject(hdc
, (HANDLE
)hbrush
);
2665 olddm
= SetROP2(hdc
, R2_XORPEN
);
2666 Rectangle(hdc
, scol
, y
* es
->txtht
, ecol
, (y
+ 1) * es
->txtht
+ 2);
2667 SetROP2(hdc
, olddm
);
2668 SelectObject(hdc
, (HANDLE
)holdbrush
);
2669 ReleaseDC(hwnd
, hdc
);
2673 /*********************************************************************
2676 * Stop text marking (selection).
2679 void EDIT_StopMarking(HWND hwnd
)
2681 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2683 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2685 TextMarking
= FALSE
;
2686 if (es
->SelBegLine
> es
->SelEndLine
)
2688 swap(&(es
->SelBegLine
), &(es
->SelEndLine
));
2689 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2691 if (es
->SelBegLine
== es
->SelEndLine
&& es
->SelBegCol
> es
->SelEndCol
)
2692 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2696 /*********************************************************************
2697 * EM_GETLINE message function
2700 LONG
EDIT_GetLineMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2704 char *buffer
= (char *)lParam
;
2706 cp
= EDIT_TextLine(hwnd
, wParam
);
2707 cp1
= EDIT_TextLine(hwnd
, wParam
+ 1);
2708 len
= min((int)(cp1
- cp
), (WORD
)(*buffer
));
2709 strncpy(buffer
, cp
, len
);
2715 /*********************************************************************
2716 * EM_GETSEL message function
2719 LONG
EDIT_GetSelMsg(HWND hwnd
)
2722 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2724 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2725 unsigned int *textPtrs
=
2726 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2728 so
= *(textPtrs
+ es
->SelBegLine
) + es
->SelBegCol
;
2729 eo
= *(textPtrs
+ es
->SelEndLine
) + es
->SelEndCol
;
2731 return MAKELONG(so
, eo
);
2735 /*********************************************************************
2736 * EM_REPLACESEL message function
2739 void EDIT_ReplaceSel(HWND hwnd
, LONG lParam
)
2741 EDIT_DeleteSel(hwnd
);
2742 EDIT_InsertText(hwnd
, (char *)lParam
, strlen((char *)lParam
));
2743 InvalidateRect(hwnd
, NULL
, TRUE
);
2748 /*********************************************************************
2751 * Insert text at current line and column.
2754 void EDIT_InsertText(HWND hwnd
, char *str
, int len
)
2757 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2759 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2760 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2762 plen
= strlen(text
) + len
;
2763 if (plen
+ 1 > es
->textlen
)
2765 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ len
);
2766 es
->textlen
= plen
+ 1;
2768 memmove(CurrChar
+ len
, CurrChar
, strlen(CurrChar
) + 1);
2769 memcpy(CurrChar
, str
, len
);
2771 EDIT_BuildTextPointers(hwnd
);
2772 es
->PaintBkgd
= TRUE
;
2773 es
->TextChanged
= TRUE
;
2775 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ len
) - text
), &(es
->CurrLine
),
2777 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2778 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2779 es
->CurrCol
, 0) - es
->wleft
;
2783 /*********************************************************************
2784 * EM_LINEFROMCHAR message function
2787 LONG
EDIT_LineFromCharMsg(HWND hwnd
, WORD wParam
)
2790 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2792 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2794 if (wParam
== (WORD
)-1)
2795 return (LONG
)(es
->SelBegLine
);
2797 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2803 /*********************************************************************
2804 * EM_LINEINDEX message function
2807 LONG
EDIT_LineIndexMsg(HWND hwnd
, WORD wParam
)
2809 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2811 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2812 unsigned int *textPtrs
=
2813 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2815 if (wParam
== (WORD
)-1)
2816 wParam
= es
->CurrLine
;
2818 return (LONG
)(*(textPtrs
+ wParam
));
2822 /*********************************************************************
2823 * EM_LINELENGTH message function
2826 LONG
EDIT_LineLengthMsg(HWND hwnd
, WORD wParam
)
2829 int sbl
, sbc
, sel
, sec
;
2830 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2832 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2833 unsigned int *textPtrs
=
2834 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2836 if (wParam
== (WORD
)-1)
2840 sbl
= es
->SelBegLine
;
2841 sbc
= es
->SelBegCol
;
2842 sel
= es
->SelEndLine
;
2843 sec
= es
->SelEndCol
;
2850 if (sbl
== sel
&& sbc
> sec
)
2855 len
= *(textPtrs
+ sbl
+ 1) - *(textPtrs
+ sbl
) - 1;
2856 return len
- sec
- sbc
;
2859 len
= *(textPtrs
+ sel
+ 1) - *(textPtrs
+ sel
) - sec
- 1;
2862 else /* no selection marked */
2864 len
= *(textPtrs
+ es
->CurrLine
+ 1) -
2865 *(textPtrs
+ es
->CurrLine
) - 1;
2869 else /* line number specified */
2871 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2872 len
= *(textPtrs
+ row
+ 1) - *(textPtrs
+ row
);
2878 /*********************************************************************
2879 * WM_SETFONT message function
2882 void EDIT_SetFont(HWND hwnd
, WORD wParam
, LONG lParam
)
2887 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2889 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2890 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
2894 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
2895 GetCharWidth(hdc
, 0, 255, charWidths
);
2896 GetTextMetrics(hdc
, &tm
);
2897 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
2898 SelectObject(hdc
, (HANDLE
)oldfont
);
2899 ReleaseDC(hwnd
, hdc
);
2901 es
->WndRow
= (es
->CurrLine
- es
->wtop
) / es
->txtht
;
2902 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2903 es
->CurrCol
, 0) - es
->wleft
;
2905 InvalidateRect(hwnd
, NULL
, TRUE
);
2906 es
->PaintBkgd
= TRUE
;
2907 if (lParam
) UpdateWindow(hwnd
);
2911 /*********************************************************************
2912 * EDIT_SaveDeletedText
2914 * Save deleted text in deleted text buffer.
2917 void EDIT_SaveDeletedText(HWND hwnd
, char *deltext
, int len
,
2921 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2923 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2925 es
->hDeletedText
= GlobalReAlloc(es
->hDeletedText
, len
, GMEM_MOVEABLE
);
2926 if (!es
->hDeletedText
) return;
2927 text
= (char *)GlobalLock(es
->hDeletedText
);
2928 memcpy(text
, deltext
, len
);
2929 GlobalUnlock(es
->hDeletedText
);
2930 es
->DeletedLength
= len
;
2931 es
->DeletedCurrLine
= line
;
2932 es
->DeletedCurrCol
= col
;
2936 /*********************************************************************
2937 * EDIT_ClearDeletedText
2939 * Clear deleted text buffer.
2942 void EDIT_ClearDeletedText(HWND hwnd
)
2944 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2946 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2948 GlobalFree(es
->hDeletedText
);
2949 es
->hDeletedText
= 0;
2950 es
->DeletedLength
= 0;
2954 /*********************************************************************
2955 * EM_UNDO message function
2958 LONG
EDIT_UndoMsg(HWND hwnd
)
2961 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2963 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2965 if (es
->hDeletedText
)
2967 text
= (char *)GlobalLock(es
->hDeletedText
);
2968 es
->CurrLine
= es
->DeletedCurrLine
;
2969 es
->CurrCol
= es
->DeletedCurrCol
;
2970 EDIT_InsertText(hwnd
, text
, es
->DeletedLength
);
2971 GlobalUnlock(es
->hDeletedText
);
2972 EDIT_ClearDeletedText(hwnd
);
2974 es
->SelBegLine
= es
->CurrLine
;
2975 es
->SelBegCol
= es
->CurrCol
;
2976 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ es
->DeletedLength
) - text
),
2977 &(es
->CurrLine
), &(es
->CurrCol
));
2978 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2979 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2980 es
->CurrCol
, 0) - es
->wleft
;
2981 es
->SelEndLine
= es
->CurrLine
;
2982 es
->SelEndCol
= es
->CurrCol
;
2984 InvalidateRect(hwnd
, NULL
, TRUE
);
2993 /*********************************************************************
2996 * Allocate the specified number of bytes on the specified local heap.
2999 unsigned int EDIT_HeapAlloc(HWND hwnd
, int bytes
)
3001 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3003 ret
= ((unsigned int)HEAP_Alloc((MDESC
**)
3004 *(LONG
*)(wndPtr
->wExtra
+ 2),
3005 GMEM_MOVEABLE
, bytes
) & 0xffff);
3007 printf("EDIT_HeapAlloc: Out of heap-memory\n");
3012 /*********************************************************************
3015 * Return the address of the memory pointed to by the handle.
3018 void *EDIT_HeapAddr(HWND hwnd
, unsigned int handle
)
3020 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3022 return ((void *)((handle
) ? ((handle
) | ((unsigned int)
3023 (*(MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2))
3024 & 0xffff0000)) : 0));
3028 /*********************************************************************
3031 * Reallocate the memory pointed to by the handle.
3034 unsigned int EDIT_HeapReAlloc(HWND hwnd
, unsigned int handle
, int bytes
)
3036 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3038 return ((unsigned int)HEAP_ReAlloc((MDESC
**)
3039 *(LONG
*)(wndPtr
->wExtra
+ 2),
3040 EDIT_HeapAddr(hwnd
, handle
),
3041 bytes
, GMEM_MOVEABLE
) & 0xffff);
3045 /*********************************************************************
3048 * Frees the memory pointed to by the handle.
3051 void EDIT_HeapFree(HWND hwnd
, unsigned int handle
)
3053 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3055 HEAP_Free((MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2),
3056 EDIT_HeapAddr(hwnd
, handle
));
3060 /*********************************************************************
3063 * Return the size of the given object on the local heap.
3066 unsigned int EDIT_HeapSize(HWND hwnd
, unsigned int handle
)
3068 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3070 return HEAP_LocalSize((MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2), handle
);
3074 /*********************************************************************
3075 * EM_SETHANDLE message function
3078 void EDIT_SetHandleMsg(HWND hwnd
, WORD wParam
)
3080 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3082 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3087 es
->textlen
= EDIT_HeapSize(hwnd
, es
->hText
);
3089 es
->wtop
= es
->wleft
= 0;
3090 es
->CurrLine
= es
->CurrCol
= 0;
3091 es
->WndRow
= es
->WndCol
= 0;
3092 es
->TextChanged
= FALSE
;
3094 es
->SelBegLine
= es
->SelBegCol
= 0;
3095 es
->SelEndLine
= es
->SelEndCol
= 0;
3096 dprintf_edit(stddeb
, "EDIT_SetHandleMsg: textlen=%d\n",
3099 EDIT_BuildTextPointers(hwnd
);
3100 es
->PaintBkgd
= TRUE
;
3101 InvalidateRect(hwnd
, NULL
, TRUE
);
3107 /*********************************************************************
3108 * EM_SETTABSTOPS message function
3111 LONG
EDIT_SetTabStopsMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
3113 unsigned short *tabstops
;
3114 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3116 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3118 es
->NumTabStops
= wParam
;
3120 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3121 else if (wParam
== 1)
3123 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3124 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3125 *tabstops
= (unsigned short)lParam
;
3129 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, wParam
);
3130 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3131 memcpy(tabstops
, (unsigned short *)lParam
, wParam
);
3137 /*********************************************************************
3138 * EDIT_CopyToClipboard
3140 * Copy the specified text to the clipboard.
3143 void EDIT_CopyToClipboard(HWND hwnd
)
3149 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3151 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3153 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
3154 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
3155 len
= (int)(bel
- bbl
);
3157 hMem
= GlobalAlloc(GHND
, (DWORD
)(len
+ 1));
3158 lpMem
= GlobalLock(hMem
);
3160 for (i
= 0; i
< len
; i
++)
3164 OpenClipboard(hwnd
);
3166 SetClipboardData(CF_TEXT
, hMem
);
3171 /*********************************************************************
3172 * WM_PASTE message function
3175 void EDIT_PasteMsg(HWND hwnd
)
3180 OpenClipboard(hwnd
);
3181 if (!(hClipMem
= GetClipboardData(CF_TEXT
)))
3183 /* no text in clipboard */
3187 lpClipMem
= GlobalLock(hClipMem
);
3188 EDIT_InsertText(hwnd
, lpClipMem
, strlen(lpClipMem
));
3189 GlobalUnlock(hClipMem
);
3191 InvalidateRect(hwnd
, NULL
, TRUE
);
3196 /*********************************************************************
3200 void swap(int *a
, int *b
)