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
)PTR_SEG_TO_LIN(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 *)PTR_SEG_TO_LIN(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
*)PTR_SEG_TO_LIN(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 */
481 if (HEAP_LocalFindHeap(createStruct
->hInstance
)!=NULL
)
482 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
483 &HEAP_LocalFindHeap(createStruct
->hInstance
)->free_list
;
486 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
487 GlobalLock(createStruct
->hInstance
);
488 /* GlobalUnlock(createStruct->hInstance); */
491 /* allocate space for state variable structure */
492 (HANDLE
)(*(wndPtr
->wExtra
)) = EDIT_HeapAlloc(hwnd
, sizeof(EDITSTATE
));
493 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
494 es
->hTextPtrs
= EDIT_HeapAlloc(hwnd
, sizeof(int));
495 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
496 es
->hCharWidths
= EDIT_HeapAlloc(hwnd
, 256 * sizeof(short));
498 /* --- text buffer */
499 es
->MaxTextLen
= MAXTEXTLEN
+ 1;
500 if (!(createStruct
->lpszName
))
502 es
->textlen
= EditBufLen(wndPtr
) + 1;
503 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
504 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
505 memset(text
, 0, es
->textlen
+ 2);
508 EDIT_ClearTextPointers(hwnd
);
512 char *windowName
= (char *)PTR_SEG_TO_LIN( createStruct
->lpszName
);
513 if (strlen(windowName
) < EditBufLen(wndPtr
))
515 es
->textlen
= EditBufLen(wndPtr
) + 1;
516 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
517 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
518 strcpy(text
, windowName
);
519 *(text
+ es
->textlen
) = '\0';
523 es
->hText
= EDIT_HeapAlloc(hwnd
, strlen(windowName
) + 2);
524 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
525 strcpy(text
, windowName
);
526 es
->textlen
= strlen(windowName
) + 1;
528 *(text
+ es
->textlen
+ 1) = '\0';
529 EDIT_BuildTextPointers(hwnd
);
532 /* ES_AUTOVSCROLL and ES_AUTOHSCROLL are automatically applied if */
533 /* the corresponding WS_* style is set */
534 if (createStruct
->style
& WS_VSCROLL
)
535 wndPtr
->dwStyle
|= ES_AUTOVSCROLL
;
536 if (createStruct
->style
& WS_HSCROLL
)
537 wndPtr
->dwStyle
|= ES_AUTOHSCROLL
;
539 /* remove the WS_CAPTION style if it has been set - this is really a */
540 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
541 if (wndPtr
->dwStyle
& WS_BORDER
&& wndPtr
->dwStyle
& WS_DLGFRAME
)
542 wndPtr
->dwStyle
^= WS_DLGFRAME
;
548 /*********************************************************************
549 * WM_CREATE message function
552 long EDIT_CreateMsg(HWND hwnd
, LONG lParam
)
555 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
557 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
563 /* initialize state variable structure */
566 /* --- char width array */
567 /* only initialise chars <= 32 as X returns strange widths */
568 /* for other chars */
569 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
570 memset(charWidths
, 0, 256 * sizeof(short));
571 GetCharWidth(hdc
, 32, 254, &charWidths
[32]);
573 /* --- other structure variables */
574 GetTextMetrics(hdc
, &tm
);
575 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
576 es
->wtop
= es
->wleft
= 0;
577 es
->CurrCol
= es
->CurrLine
= 0;
578 es
->WndCol
= es
->WndRow
= 0;
579 es
->TextChanged
= FALSE
;
580 es
->SelBegLine
= es
->SelBegCol
= 0;
581 es
->SelEndLine
= es
->SelEndCol
= 0;
583 es
->hDeletedText
= 0;
584 es
->DeletedLength
= 0;
586 es
->hTabStops
= EDIT_HeapAlloc(hwnd
, sizeof(int));
588 /* allocate space for a line full of blanks to speed up */
590 es
->hBlankLine
= EDIT_HeapAlloc(hwnd
, (ClientWidth(wndPtr
) /
591 charWidths
[32]) + 2);
592 text
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
593 memset(text
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
595 /* set up text cursor for edit class */
596 CLASS_FindClassByName("EDIT", 0, &classPtr
);
597 classPtr
->wc
.hCursor
= LoadCursor(0, IDC_IBEAM
);
599 /* paint background on first WM_PAINT */
600 es
->PaintBkgd
= TRUE
;
602 ReleaseDC(hwnd
, hdc
);
607 /*********************************************************************
608 * EDIT_ClearTextPointers
610 * Clear and initialize text line pointer array.
613 void EDIT_ClearTextPointers(HWND hwnd
)
615 unsigned int *textPtrs
;
616 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
618 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
620 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
, sizeof(int));
621 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
626 /*********************************************************************
627 * EDIT_BuildTextPointers
629 * Build array of pointers to text lines.
632 #define INITLINES 100
634 void EDIT_BuildTextPointers(HWND hwnd
)
636 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
638 int incrs
= INITLINES
;
639 unsigned int off
, len
;
641 unsigned int *textPtrs
;
644 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
645 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
646 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
647 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
649 es
->textwidth
= es
->wlines
= 0;
652 /* advance through text buffer */
655 /* increase size of text pointer array */
656 if (incrs
== INITLINES
)
659 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
,
660 (es
->wlines
+ INITLINES
) * sizeof(int));
661 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
663 off
= (unsigned int)(cp
- text
); /* offset of beginning of line */
664 *(textPtrs
+ es
->wlines
) = off
;
669 /* advance through current line */
670 while (*cp
&& *cp
!= '\n')
672 len
+= EDIT_CharWidth(hwnd
, (BYTE
)*cp
, len
);
673 /* width of line in pixels */
676 es
->textwidth
= max(es
->textwidth
, len
);
678 cp
++; /* skip '\n' */
681 off
= (unsigned int)(cp
- text
);
682 *(textPtrs
+ es
->wlines
) = off
;
686 /*********************************************************************
687 * EDIT_ModTextPointers
689 * Modify text pointers from a specified position.
692 void EDIT_ModTextPointers(HWND hwnd
, int lineno
, int var
)
694 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
696 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
697 unsigned int *textPtrs
=
698 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
700 while (lineno
< es
->wlines
)
701 *(textPtrs
+ lineno
++) += var
;
705 /*********************************************************************
706 * WM_PAINT message function
709 void EDIT_PaintMsg(HWND hwnd
)
715 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
717 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
719 hdc
= BeginPaint(hwnd
, &ps
);
722 dprintf_edit(stddeb
,"WM_PAINT: rc=(%d,%d), (%d,%d)\n", rc
.left
, rc
.top
,
723 rc
.right
, rc
.bottom
);
726 FillWindow(GetParent(hwnd
), hwnd
, hdc
, CTLCOLOR_EDIT
);
728 for (y
= (rc
.top
/ es
->txtht
); y
<= (rc
.bottom
/ es
->txtht
); y
++)
730 if (y
< es
->wlines
- es
->wtop
)
731 EDIT_WriteTextLine(hwnd
, &rc
, y
+ es
->wtop
);
738 /*********************************************************************
741 * Get a copy of the text in the specified line.
744 HANDLE
EDIT_GetTextLine(HWND hwnd
, int selection
)
751 dprintf_edit(stddeb
,"GetTextLine %d\n", selection
);
752 cp
= cp1
= EDIT_TextLine(hwnd
, selection
);
753 /* advance through line */
754 while (*cp
&& *cp
!= '\r')
760 /* store selected line and return handle */
761 hLine
= EDIT_HeapAlloc(hwnd
, len
+ 6);
762 line
= (char *)EDIT_HeapAddr(hwnd
, hLine
);
763 memmove(line
, cp1
, len
);
769 /*********************************************************************
772 * Return a pointer to the text in the specified line.
775 char *EDIT_TextLine(HWND hwnd
, int sel
)
777 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
779 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
780 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
781 unsigned int *textPtrs
=
782 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
784 if(sel
>es
->wlines
)return NULL
;
785 return (text
+ *(textPtrs
+ sel
));
789 /*********************************************************************
792 * Return length of string _str_ of length _len_ characters in pixels.
793 * The current column offset in pixels _pcol_ is required to calculate
794 * the width of a tab.
797 int EDIT_StrLength(HWND hwnd
, unsigned char *str
, int len
, int pcol
)
801 for (i
= 0; i
< len
; i
++)
802 plen
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(str
+ i
)), pcol
+ plen
);
804 dprintf_edit(stddeb
,"EDIT_StrLength: returning %d\n", plen
);
809 /*********************************************************************
812 * Return length of line _num_ in characters.
815 int EDIT_LineLength(HWND hwnd
, int num
)
817 char *cp
= EDIT_TextLine(hwnd
, num
);
821 cp1
= strchr(cp
, '\r');
822 return cp1
? (int)(cp1
- cp
) : strlen(cp
);
826 /*********************************************************************
829 * Write the line of text at offset _y_ in text buffer to a window.
832 void EDIT_WriteTextLine(HWND hwnd
, RECT
*rect
, int y
)
839 int sbl
, sel
, sbc
, sec
;
841 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
843 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
845 /* initialize rectangle if NULL, else copy */
849 GetClientRect(hwnd
, &rc
);
851 dprintf_edit(stddeb
,"WriteTextLine %d\n", y
);
853 /* make sure y is inside the window */
854 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
856 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is not a displayed line\n", y
);
860 /* make sure rectangle is within window */
861 if (rc
.left
>= ClientWidth(wndPtr
) - 1)
863 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.left (%d) is greater than right edge\n",
869 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.right (%d) is less than left edge\n",
873 if (y
- es
->wtop
< (rc
.top
/ es
->txtht
) ||
874 y
- es
->wtop
> (rc
.bottom
/ es
->txtht
))
876 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is outside window\n", y
);
880 /* get the text and length of line */
881 if ((hLine
= EDIT_GetTextLine(hwnd
, y
)) == 0)
883 lp
= (unsigned char *)EDIT_HeapAddr(hwnd
, hLine
);
884 lnlen
= EDIT_StrLength(hwnd
, lp
, strlen(lp
), 0);
887 /* build the line to display */
888 if (lnlen
< es
->wleft
)
896 lnlen
= lnlen1
- off
;
897 len
= min(lnlen
, rc
.right
- rc
.left
);
902 sbl
= es
->SelBegLine
;
903 sel
= es
->SelEndLine
;
907 /* put lowest marker first */
913 if (sbl
== sel
&& sbc
> sec
)
916 if (y
< sbl
|| y
> sel
)
917 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
919 else if (y
> sbl
&& y
< sel
)
920 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
924 col
= EDIT_StrLength(hwnd
, lp
, sbc
, 0);
925 if (col
> (es
->wleft
+ rc
.left
))
927 len
= min(col
- off
, rc
.right
- off
);
928 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
929 rc
.left
, &rc
, FALSE
, FALSE
);
934 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
935 if (col
< (es
->wleft
+ rc
.right
))
937 len
= min(col
- off
, rc
.right
- off
);
938 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
939 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
941 len
= min(lnlen
- off
, rc
.right
- off
);
942 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
943 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
947 len
= min(lnlen
- off
, rc
.right
- off
);
948 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
949 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
954 len
= min(lnlen
- off
, rc
.right
- off
);
955 if (col
< (es
->wleft
+ rc
.right
))
956 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
957 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
962 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
963 if (col
< (es
->wleft
+ rc
.right
))
965 len
= min(col
- off
, rc
.right
- off
);
966 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
967 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
969 len
= min(lnlen
- off
, rc
.right
- off
);
970 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
971 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
976 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
979 EDIT_HeapFree(hwnd
, hLine
);
983 /*********************************************************************
986 * Write text to a window
988 * off - offset in text line (in pixels)
989 * len - length from off (in pixels)
990 * row - line in window
991 * col - column in window
992 * rc - rectangle in which to display line
993 * blank - blank remainder of line?
994 * reverse - reverse color of line?
997 void EDIT_WriteText(HWND hwnd
, char *lp
, int off
, int len
, int row
,
998 int col
, RECT
*rc
, BOOL blank
, BOOL reverse
)
1002 char *str
, *cp
, *cp1
;
1003 int diff
=0, num_spaces
, tabwidth
, scol
;
1005 COLORREF oldTextColor
, oldBkgdColor
;
1007 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1009 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1010 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1011 char *blanks
= (char *)EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1013 dprintf_edit(stddeb
,"EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp
, off
, len
, row
, col
, reverse
);
1022 hStr
= EDIT_GetStr(hwnd
, lp
, off
, len
, &diff
);
1023 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1024 hrgnClip
= CreateRectRgnIndirect(rc
);
1025 SelectClipRgn(hdc
, hrgnClip
);
1028 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
1030 SendMessage(GetParent(hwnd
), WM_CTLCOLOR
, (WORD
)hdc
,
1031 MAKELPARAM(hwnd
, CTLCOLOR_EDIT
));
1035 oldBkgdColor
= GetBkColor(hdc
);
1036 oldTextColor
= GetTextColor(hdc
);
1037 SetBkColor(hdc
, oldTextColor
);
1038 SetTextColor(hdc
, oldBkgdColor
);
1041 if (strlen(blanks
) < (ClientWidth(wndPtr
) / charWidths
[32]) + 2)
1043 es
->hBlankLine
= EDIT_HeapReAlloc(hwnd
, es
->hBlankLine
,
1044 (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1045 blanks
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1046 memset(blanks
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1049 if (!(cp
= strchr(str
, VK_TAB
)))
1050 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, strlen(str
));
1053 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, (int)(cp
- str
));
1054 scol
= EDIT_StrLength(hwnd
, str
, (int)(cp
- str
), 0);
1055 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1056 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1057 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1061 while ((cp1
= strchr(cp
, VK_TAB
)))
1063 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, (int)(cp1
- cp
));
1064 scol
+= EDIT_StrLength(hwnd
, cp
, (int)(cp1
- cp
), scol
);
1065 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1066 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1067 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1072 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, strlen(cp
));
1077 SetBkColor(hdc
, oldBkgdColor
);
1078 SetTextColor(hdc
, oldTextColor
);
1081 /* blank out remainder of line if appropriate */
1084 if ((rc
->right
- col
) > len
)
1086 num_spaces
= (rc
->right
- col
- len
) / charWidths
[32];
1087 TextOut(hdc
, col
+ len
, row
* es
->txtht
, blanks
, num_spaces
);
1092 SelectObject(hdc
, (HANDLE
)oldfont
);
1094 EDIT_HeapFree(hwnd
, hStr
);
1095 ReleaseDC(hwnd
, hdc
);
1099 /*********************************************************************
1102 * Return sub-string starting at pixel _off_ of length _len_ pixels.
1103 * If _off_ is part way through a character, the negative offset of
1104 * the beginning of the character is returned in _diff_, else _diff_
1108 HANDLE
EDIT_GetStr(HWND hwnd
, char *lp
, int off
, int len
, int *diff
)
1112 int ch
= 0, i
= 0, j
, s_i
=0;
1115 dprintf_edit(stddeb
,"EDIT_GetStr lp='%s' off=%d len=%d\n", lp
, off
, len
);
1117 if (off
< 0) off
= 0;
1121 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1124 /* if stepped past _off_, go back a character */
1132 while (i
< len
+ off
)
1134 if (*(lp
+ ch
) == '\r' || *(lp
+ ch
) == '\n')
1136 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1140 hStr
= EDIT_HeapAlloc(hwnd
, ch
- ch1
+ 3);
1141 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1142 for (i
= ch1
, j
= 0; i
< ch
; i
++, j
++)
1145 dprintf_edit(stddeb
,"EDIT_GetStr: returning %s\n", str
);
1150 /*********************************************************************
1151 * WM_CHAR message function
1154 void EDIT_CharMsg(HWND hwnd
, WORD wParam
)
1156 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1158 dprintf_edit(stddeb
,"EDIT_CharMsg: wParam=%c\n", (char)wParam
);
1167 EDIT_KeyTyped(hwnd
, wParam
);
1173 EDIT_KeyTyped(hwnd
, wParam
);
1177 if (wParam
>= 20 && wParam
<= 254 && wParam
!= 127 )
1178 EDIT_KeyTyped(hwnd
, wParam
);
1184 /*********************************************************************
1187 * Process keystrokes that produce displayable characters.
1190 void EDIT_KeyTyped(HWND hwnd
, short ch
)
1192 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1194 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1195 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1196 char *currchar
= CurrChar
;
1198 BOOL FullPaint
= FALSE
;
1200 dprintf_edit(stddeb
,"EDIT_KeyTyped: ch=%c\n", (char)ch
);
1202 /* delete selected text (if any) */
1204 EDIT_DeleteSel(hwnd
);
1206 /* test for typing at end of maximum buffer size */
1207 if (currchar
== text
+ es
->MaxTextLen
)
1209 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1213 if (*currchar
== '\0' && IsMultiLine())
1215 /* insert a newline at end of text */
1217 *(currchar
+ 1) = '\n';
1218 *(currchar
+ 2) = '\0';
1219 EDIT_BuildTextPointers(hwnd
);
1222 /* insert the typed character */
1223 if (text
[es
->textlen
- 1] != '\0')
1225 /* current text buffer is full */
1226 if (es
->textlen
== es
->MaxTextLen
)
1228 /* text buffer is at maximum size */
1229 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1233 /* increase the text buffer size */
1234 es
->textlen
+= GROWLENGTH
;
1235 /* but not above maximum size */
1236 if (es
->textlen
> es
->MaxTextLen
)
1237 es
->textlen
= es
->MaxTextLen
;
1238 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ 2);
1240 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1241 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1242 text
[es
->textlen
- 1] = '\0';
1243 currchar
= CurrChar
;
1245 /* make space for new character and put char in buffer */
1248 memmove(currchar
+ 2, currchar
, strlen(currchar
) + 1);
1250 *(currchar
+ 1) = '\n';
1251 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, 2);
1255 memmove(currchar
+ 1, currchar
, strlen(currchar
) + 1);
1257 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, 1);
1259 es
->TextChanged
= TRUE
;
1260 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1262 /* re-adjust textwidth, if necessary, and redraw line */
1264 if (IsMultiLine() && es
->wlines
> 1)
1266 es
->textwidth
= max(es
->textwidth
,
1267 EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
1268 (int)(EDIT_TextLine(hwnd
, es
->CurrLine
+ 1) -
1269 EDIT_TextLine(hwnd
, es
->CurrLine
)), 0));
1272 es
->textwidth
= max(es
->textwidth
,
1273 EDIT_StrLength(hwnd
, text
, strlen(text
), 0));
1274 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ es
->WndRow
);
1281 EDIT_BuildTextPointers(hwnd
);
1285 /* invalidate rest of window */
1286 GetClientRect(hwnd
, &rc
);
1288 rc
.top
= es
->WndRow
* es
->txtht
;
1289 InvalidateRect(hwnd
, &rc
, FALSE
);
1291 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1294 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1298 /* test end of window */
1299 if (es
->WndCol
>= ClientWidth(wndPtr
) -
1300 EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
))
1302 /* TODO:- Word wrap to be handled here */
1304 /* if (!(currchar == text + es->MaxTextLen - 2)) */
1305 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1307 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
);
1309 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1311 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1315 /*********************************************************************
1318 * Return the width of the given character in pixels.
1319 * The current column offset in pixels _pcol_ is required to calculate
1320 * the width of a tab.
1323 int EDIT_CharWidth(HWND hwnd
, short ch
, int pcol
)
1325 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1327 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1328 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1331 return (charWidths
[ch
]);
1333 return (EDIT_GetNextTabStop(hwnd
, pcol
) - pcol
);
1337 /*********************************************************************
1338 * EDIT_GetNextTabStop
1340 * Return the next tab stop beyond _pcol_.
1343 int EDIT_GetNextTabStop(HWND hwnd
, int pcol
)
1346 int baseUnitWidth
= LOWORD(GetDialogBaseUnits());
1347 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1349 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1350 unsigned short *tabstops
= EDIT_HeapAddr(hwnd
, es
->hTabStops
);
1352 if (es
->NumTabStops
== 0)
1353 return ROUNDUP(pcol
, 8 * baseUnitWidth
);
1354 else if (es
->NumTabStops
== 1)
1355 return ROUNDUP(pcol
, *tabstops
* baseUnitWidth
/ 4);
1358 for (i
= 0; i
< es
->NumTabStops
; i
++)
1360 if (*(tabstops
+ i
) * baseUnitWidth
/ 4 >= pcol
)
1361 return (*(tabstops
+ i
) * baseUnitWidth
/ 4);
1368 /*********************************************************************
1371 * Cursor right key: move right one character position.
1374 void EDIT_Forward(HWND hwnd
)
1376 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1378 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1380 if (*CurrChar
== '\0')
1383 if (*CurrChar
== '\r')
1386 EDIT_Downward(hwnd
);
1390 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1392 if (es
->WndCol
>= ClientWidth(wndPtr
))
1393 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1399 /*********************************************************************
1402 * Cursor down key: move down one line.
1405 void EDIT_Downward(HWND hwnd
)
1407 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1409 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1411 dprintf_edit(stddeb
,"EDIT_Downward: WndRow=%d, wtop=%d, wlines=%d\n",
1412 es
->WndRow
, es
->wtop
, es
->wlines
);
1414 if (IsMultiLine() && (es
->WndRow
+ es
->wtop
+ 1 < es
->wlines
))
1417 if (es
->WndRow
== ClientHeight(wndPtr
, es
) - 1)
1420 EDIT_KeyVScrollLine(hwnd
, SB_LINEDOWN
);
1424 EDIT_StickEnd(hwnd
);
1429 /*********************************************************************
1432 * Cursor up key: move up one line.
1435 void EDIT_Upward(HWND hwnd
)
1437 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1439 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1441 if (IsMultiLine() && es
->CurrLine
!= 0)
1444 if (es
->WndRow
== 0)
1447 EDIT_KeyVScrollLine(hwnd
, SB_LINEUP
);
1451 EDIT_StickEnd(hwnd
);
1456 /*********************************************************************
1459 * Cursor left key: move left one character position.
1462 void EDIT_Backward(HWND hwnd
)
1464 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1466 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1471 if (*CurrChar
== VK_TAB
)
1472 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
),
1473 EDIT_StrLength(hwnd
,
1474 EDIT_TextLine(hwnd
, es
->CurrLine
),
1477 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), 0);
1479 EDIT_KeyHScroll(hwnd
, SB_LINEUP
);
1481 else if (IsMultiLine() && es
->CurrLine
!= 0)
1489 /*********************************************************************
1492 * End key: move to end of line.
1495 void EDIT_End(HWND hwnd
)
1497 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1499 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1501 while (*CurrChar
&& *CurrChar
!= '\r')
1503 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1507 if (es
->WndCol
>= ClientWidth(wndPtr
))
1509 es
->wleft
= es
->WndCol
- ClientWidth(wndPtr
) + HSCROLLDIM
;
1510 es
->WndCol
-= es
->wleft
;
1511 InvalidateRect(hwnd
, NULL
, FALSE
);
1517 /*********************************************************************
1520 * Home key: move to beginning of line.
1523 void EDIT_Home(HWND hwnd
)
1525 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1527 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1529 es
->CurrCol
= es
->WndCol
= 0;
1533 InvalidateRect(hwnd
, NULL
, FALSE
);
1539 /*********************************************************************
1542 * Stick the cursor to the end of the line.
1545 void EDIT_StickEnd(HWND hwnd
)
1547 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1549 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1550 int len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
1551 char *cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
1554 es
->CurrCol
= min(len
, es
->CurrCol
);
1555 es
->WndCol
= min(EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
, es
->WndCol
);
1556 currpel
= EDIT_StrLength(hwnd
, cp
, es
->CurrCol
, 0);
1558 if (es
->wleft
> currpel
)
1560 es
->wleft
= max(0, currpel
- 20);
1561 es
->WndCol
= currpel
- es
->wleft
;
1564 else if (currpel
- es
->wleft
>= ClientWidth(wndPtr
))
1566 es
->wleft
= currpel
- (ClientWidth(wndPtr
) - 5);
1567 es
->WndCol
= currpel
- es
->wleft
;
1573 /*********************************************************************
1574 * WM_KEYDOWN message function
1577 void EDIT_KeyDownMsg(HWND hwnd
, WORD wParam
)
1579 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1581 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1583 dprintf_edit(stddeb
,"EDIT_KeyDownMsg: key=%x\n", wParam
);
1590 EDIT_ClearSel(hwnd
);
1594 EDIT_Backward(hwnd
);
1599 EDIT_ClearSel(hwnd
);
1601 EDIT_Downward(hwnd
);
1608 EDIT_ClearSel(hwnd
);
1614 EDIT_ClearSel(hwnd
);
1615 EDIT_Backward(hwnd
);
1620 EDIT_ClearSel(hwnd
);
1626 EDIT_ClearSel(hwnd
);
1634 EDIT_ClearSel(hwnd
);
1635 EDIT_KeyVScrollPage(hwnd
, SB_PAGEUP
);
1643 EDIT_ClearSel(hwnd
);
1644 EDIT_KeyVScrollPage(hwnd
, SB_PAGEDOWN
);
1650 EDIT_DeleteSel(hwnd
);
1653 if (es
->CurrCol
== 0 && es
->CurrLine
== 0)
1655 EDIT_Backward(hwnd
);
1662 EDIT_DeleteSel(hwnd
);
1668 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1673 /*********************************************************************
1676 * Scroll text horizontally using cursor keys.
1679 void EDIT_KeyHScroll(HWND hwnd
, WORD opt
)
1682 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1684 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1686 if (opt
== SB_LINEDOWN
)
1688 es
->wleft
+= HSCROLLDIM
;
1689 es
->WndCol
-= HSCROLLDIM
;
1695 if (es
->wleft
- HSCROLLDIM
< 0)
1697 es
->WndCol
+= es
->wleft
;
1702 es
->wleft
-= HSCROLLDIM
;
1703 es
->WndCol
+= HSCROLLDIM
;
1707 InvalidateRect(hwnd
, NULL
, FALSE
);
1712 hscrollpos
= EDIT_ComputeHScrollPos(hwnd
);
1713 SetScrollPos(hwnd
, SB_HORZ
, hscrollpos
, TRUE
);
1718 /*********************************************************************
1719 * EDIT_KeyVScrollLine
1721 * Scroll text vertically by one line using keyboard.
1724 void EDIT_KeyVScrollLine(HWND hwnd
, WORD opt
)
1728 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1730 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1735 if (opt
== SB_LINEDOWN
)
1737 /* move down one line */
1738 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
1744 /* move up one line */
1750 if (IsWindowVisible(hwnd
))
1752 /* adjust client bottom to nearest whole line */
1753 GetClientRect(hwnd
, &rc
);
1754 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
1756 if (opt
== SB_LINEUP
)
1758 /* move up one line (scroll window down) */
1759 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
1760 /* write top line */
1761 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
1766 /* move down one line (scroll window up) */
1767 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
1768 /* write bottom line */
1769 y
= (((rc
.bottom
- rc
.top
) / es
->txtht
) - 1);
1770 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
1775 /* reset the vertical scroll bar */
1778 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1779 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1784 /*********************************************************************
1785 * EDIT_KeyVScrollPage
1787 * Scroll text vertically by one page using keyboard.
1790 void EDIT_KeyVScrollPage(HWND hwnd
, WORD opt
)
1793 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1795 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1799 if (opt
== SB_PAGEUP
)
1802 es
->wtop
-= ClientHeight(wndPtr
, es
);
1806 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1808 es
->wtop
+= ClientHeight(wndPtr
, es
);
1809 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
1810 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1816 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
1817 EDIT_StickEnd(hwnd
);
1818 InvalidateRect(hwnd
, NULL
, TRUE
);
1821 /* reset the vertical scroll bar */
1824 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1825 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1831 /*********************************************************************
1832 * EDIT_KeyVScrollDoc
1834 * Scroll text to top and bottom of document using keyboard.
1837 void EDIT_KeyVScrollDoc(HWND hwnd
, WORD opt
)
1840 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1842 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1848 es
->wtop
= es
->wleft
= 0;
1849 else if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1851 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1855 es
->CurrLine
= es
->wlines
;
1856 es
->WndRow
= es
->wlines
- es
->wtop
;
1858 InvalidateRect(hwnd
, NULL
, TRUE
);
1861 /* reset the vertical scroll bar */
1864 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1865 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1870 /*********************************************************************
1871 * EDIT_ComputeVScrollPos
1873 * Compute the vertical scroll bar position from the window
1874 * position and text width.
1877 int EDIT_ComputeVScrollPos(HWND hwnd
)
1880 short minpos
, maxpos
;
1881 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1883 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1885 GetScrollRange(hwnd
, SB_VERT
, &minpos
, &maxpos
);
1887 if (es
->wlines
> ClientHeight(wndPtr
, es
))
1888 vscrollpos
= (double)(es
->wtop
) / (double)(es
->wlines
-
1889 ClientHeight(wndPtr
, es
)) * (maxpos
- minpos
);
1891 vscrollpos
= minpos
;
1897 /*********************************************************************
1898 * EDIT_ComputeHScrollPos
1900 * Compute the horizontal scroll bar position from the window
1901 * position and text width.
1904 int EDIT_ComputeHScrollPos(HWND hwnd
)
1907 short minpos
, maxpos
;
1908 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1910 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1912 GetScrollRange(hwnd
, SB_HORZ
, &minpos
, &maxpos
);
1914 if (es
->textwidth
> ClientWidth(wndPtr
))
1915 hscrollpos
= (double)(es
->wleft
) / (double)(es
->textwidth
-
1916 ClientWidth(wndPtr
)) * (maxpos
- minpos
);
1918 hscrollpos
= minpos
;
1924 /*********************************************************************
1927 * Delete character to right of cursor.
1930 void EDIT_DelKey(HWND hwnd
)
1933 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1935 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1936 char *currchar
= CurrChar
;
1937 BOOL repaint
= *currchar
== '\n';
1939 if (IsMultiLine() && *currchar
== '\n' && *(currchar
+ 1) == '\0')
1941 strcpy(currchar
, currchar
+ 1);
1942 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1946 EDIT_BuildTextPointers(hwnd
);
1947 GetClientRect(hwnd
, &rc
);
1948 rc
.top
= es
->WndRow
* es
->txtht
;
1949 InvalidateRect(hwnd
, &rc
, FALSE
);
1954 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, -1);
1955 EDIT_WriteTextLine(hwnd
, NULL
, es
->WndRow
+ es
->wtop
);
1958 es
->TextChanged
= TRUE
;
1959 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1962 /*********************************************************************
1963 * WM_VSCROLL message function
1966 void EDIT_VScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
1968 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1970 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1980 EDIT_VScrollLine(hwnd
, wParam
);
1985 EDIT_VScrollPage(hwnd
, wParam
);
1990 SetCaretPos(es
->WndCol
, es
->WndRow
);
1995 /*********************************************************************
1998 * Scroll text vertically by one line using scrollbars.
2001 void EDIT_VScrollLine(HWND hwnd
, WORD opt
)
2005 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2007 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2009 dprintf_edit(stddeb
,"EDIT_VScrollLine: direction=%d\n", opt
);
2011 if (opt
== SB_LINEDOWN
)
2013 /* move down one line */
2014 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
2020 /* move up one line */
2026 if (IsWindowVisible(hwnd
))
2028 /* adjust client bottom to nearest whole line */
2029 GetClientRect(hwnd
, &rc
);
2030 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
2032 if (opt
== SB_LINEUP
)
2034 /* move up one line (scroll window down) */
2035 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
2036 /* write top line */
2037 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
2042 /* move down one line (scroll window up) */
2043 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
2044 /* write bottom line */
2045 y
= ((rc
.bottom
- rc
.top
/ es
->txtht
) - 1);
2046 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
2053 /*********************************************************************
2056 * Scroll text vertically by one page using keyboard.
2059 void EDIT_VScrollPage(HWND hwnd
, WORD opt
)
2062 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2064 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2066 if (opt
== SB_PAGEUP
)
2069 es
->wtop
-= ClientHeight(wndPtr
, es
);
2073 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
2075 es
->wtop
+= ClientHeight(wndPtr
, es
);
2076 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
2077 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
2083 InvalidateRect(hwnd
, NULL
, TRUE
);
2086 /* reset the vertical scroll bar */
2089 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
2090 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
2095 /*********************************************************************
2096 * WM_HSCROLL message function
2099 void EDIT_HScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2101 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2103 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2111 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
2118 /*********************************************************************
2119 * WM_SIZE message function
2122 void EDIT_SizeMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2124 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2126 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2128 if (wParam
!= SIZE_MAXIMIZED
&& wParam
!= SIZE_RESTORED
) return;
2130 InvalidateRect(hwnd
, NULL
, TRUE
);
2131 es
->PaintBkgd
= TRUE
;
2136 /*********************************************************************
2137 * WM_LBUTTONDOWN message function
2140 void EDIT_LButtonDownMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2145 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2147 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2150 EDIT_ClearSel(hwnd
);
2152 es
->WndRow
= HIWORD(lParam
) / es
->txtht
;
2153 if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2156 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2161 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2163 cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
2164 len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
2165 es
->WndCol
= LOWORD(lParam
);
2166 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
|| end
)
2167 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
;
2168 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2171 ButtonRow
= es
->CurrLine
;
2172 ButtonCol
= es
->CurrCol
;
2176 /*********************************************************************
2177 * WM_MOUSEMOVE message function
2180 void EDIT_MouseMoveMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2182 if (wParam
!= MK_LBUTTON
)
2187 EDIT_SetAnchor(hwnd
, ButtonRow
, ButtonCol
);
2193 EDIT_ExtendSel(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
2197 /*********************************************************************
2200 * Convert a pixel offset in the given row to a character offset,
2201 * adjusting the pixel offset to the nearest whole character if
2205 int EDIT_PixelToChar(HWND hwnd
, int row
, int *pixel
)
2207 int ch
= 0, i
= 0, s_i
= 0;
2210 dprintf_edit(stddeb
,"EDIT_PixelToChar: row=%d, pixel=%d\n", row
, *pixel
);
2212 text
= EDIT_TextLine(hwnd
, row
);
2216 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(text
+ ch
)), i
);
2220 /* if stepped past _pixel_, go back a character */
2231 /*********************************************************************
2232 * WM_SETTEXT message function
2235 LONG
EDIT_SetTextMsg(HWND hwnd
, LONG lParam
)
2239 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2241 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2243 if (strlen((char *)PTR_SEG_TO_LIN(lParam
)) <= es
->MaxTextLen
)
2245 len
= ( lParam
? strlen((char *)PTR_SEG_TO_LIN(lParam
)) : 0 );
2246 EDIT_ClearText(hwnd
);
2248 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, len
+ 3);
2249 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2251 strcpy(text
, (char *)PTR_SEG_TO_LIN(lParam
));
2253 text
[len
+ 1] = '\0';
2254 text
[len
+ 2] = '\0';
2255 EDIT_BuildTextPointers(hwnd
);
2256 InvalidateRect(hwnd
, NULL
, TRUE
);
2257 es
->PaintBkgd
= TRUE
;
2258 es
->TextChanged
= TRUE
;
2266 /*********************************************************************
2269 * Clear text from text buffer.
2272 void EDIT_ClearText(HWND hwnd
)
2274 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2276 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2277 unsigned int blen
= EditBufLen(wndPtr
) + 2;
2280 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, blen
);
2281 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2282 memset(text
, 0, blen
);
2285 es
->CurrLine
= es
->CurrCol
= 0;
2286 es
->WndRow
= es
->WndCol
= 0;
2287 es
->wleft
= es
->wtop
= 0;
2289 es
->TextChanged
= FALSE
;
2290 EDIT_ClearTextPointers(hwnd
);
2294 /*********************************************************************
2295 * EM_SETSEL message function
2298 void EDIT_SetSelMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2301 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2303 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2305 so
= LOWORD(lParam
);
2306 eo
= HIWORD(lParam
);
2308 if (so
== -1) /* if so == -1, clear selection */
2310 EDIT_ClearSel(hwnd
);
2314 if (so
== eo
) /* if so == eo, set caret only */
2316 EDIT_GetLineCol(hwnd
, so
, &(es
->CurrLine
), &(es
->CurrCol
));
2317 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2321 if (es
->WndRow
< 0 || es
->WndRow
> ClientHeight(wndPtr
, es
))
2323 es
->wtop
= es
->CurrLine
;
2326 es
->WndCol
= EDIT_StrLength(hwnd
,
2327 EDIT_TextLine(hwnd
, es
->CurrLine
),
2328 es
->CurrCol
, 0) - es
->wleft
;
2329 if (es
->WndCol
> ClientWidth(wndPtr
))
2331 es
->wleft
= es
->WndCol
;
2334 else if (es
->WndCol
< 0)
2336 es
->wleft
+= es
->WndCol
;
2341 else /* otherwise set selection */
2346 EDIT_GetLineCol(hwnd
, so
, &(es
->SelBegLine
), &(es
->SelBegCol
));
2347 EDIT_GetLineCol(hwnd
, eo
, &(es
->SelEndLine
), &(es
->SelEndCol
));
2348 es
->CurrLine
= es
->SelEndLine
;
2349 es
->CurrCol
= es
->SelEndCol
;
2350 es
->WndRow
= es
->SelEndLine
- es
->wtop
;
2352 if (!wParam
) /* don't suppress scrolling of text */
2356 es
->wtop
= es
->SelEndLine
;
2359 else if (es
->WndRow
> ClientHeight(wndPtr
, es
))
2361 es
->wtop
+= es
->WndRow
- ClientHeight(wndPtr
, es
);
2362 es
->WndRow
= ClientHeight(wndPtr
, es
);
2364 es
->WndCol
= EDIT_StrLength(hwnd
,
2365 EDIT_TextLine(hwnd
, es
->SelEndLine
),
2366 es
->SelEndCol
, 0) - es
->wleft
;
2367 if (es
->WndCol
> ClientWidth(wndPtr
))
2369 es
->wleft
+= es
->WndCol
- ClientWidth(wndPtr
);
2370 es
->WndCol
= ClientWidth(wndPtr
);
2372 else if (es
->WndCol
< 0)
2374 es
->wleft
+= es
->WndCol
;
2379 InvalidateRect(hwnd
, NULL
, TRUE
);
2385 /*********************************************************************
2388 * Return line and column in text buffer from character offset.
2391 void EDIT_GetLineCol(HWND hwnd
, int off
, int *line
, int *col
)
2395 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2397 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2398 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2399 unsigned int *textPtrs
=
2400 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2402 /* check for (0,0) */
2403 if (!off
|| !es
->wlines
)
2410 if (off
> strlen(text
)) off
= strlen(text
);
2412 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2414 cp
= text
+ *(textPtrs
+ lineno
);
2415 if (off
== (int)(cp
- text
))
2421 if (off
< (int)(cp
- text
))
2426 *col
= off
- (int)(cp1
- text
);
2428 if (*(text
+ *col
) == '\0')
2434 /*********************************************************************
2437 * Delete the current selected text (if any)
2440 void EDIT_DeleteSel(HWND hwnd
)
2444 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2446 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2450 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
2451 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
2452 len
= (int)(bel
- bbl
);
2453 EDIT_SaveDeletedText(hwnd
, bbl
, len
, es
->SelBegLine
, es
->SelBegCol
);
2454 es
->TextChanged
= TRUE
;
2457 es
->CurrLine
= es
->SelBegLine
;
2458 es
->CurrCol
= es
->SelBegCol
;
2459 es
->WndRow
= es
->SelBegLine
- es
->wtop
;
2462 es
->wtop
= es
->SelBegLine
;
2465 es
->WndCol
= EDIT_StrLength(hwnd
, bbl
- es
->SelBegCol
,
2466 es
->SelBegCol
, 0) - es
->wleft
;
2468 EDIT_BuildTextPointers(hwnd
);
2469 es
->PaintBkgd
= TRUE
;
2470 EDIT_ClearSel(hwnd
);
2475 /*********************************************************************
2478 * Clear the current selection.
2481 void EDIT_ClearSel(HWND hwnd
)
2483 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2485 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2487 es
->SelBegLine
= es
->SelBegCol
= 0;
2488 es
->SelEndLine
= es
->SelEndCol
= 0;
2490 InvalidateRect(hwnd
, NULL
, TRUE
);
2495 /*********************************************************************
2496 * EDIT_TextLineNumber
2498 * Return the line number in the text buffer of the supplied
2499 * character pointer.
2502 int EDIT_TextLineNumber(HWND hwnd
, char *lp
)
2506 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2508 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2509 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2510 unsigned int *textPtrs
=
2511 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2513 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2515 cp
= text
+ *(textPtrs
+ lineno
);
2525 /*********************************************************************
2528 * Set down anchor for text marking.
2531 void EDIT_SetAnchor(HWND hwnd
, int row
, int col
)
2534 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2536 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2540 EDIT_ClearSel(hwnd
);
2541 es
->SelBegLine
= es
->SelEndLine
= row
;
2542 es
->SelBegCol
= es
->SelEndCol
= col
;
2545 InvalidateRect(hwnd
, NULL
, FALSE
);
2551 /*********************************************************************
2554 * Extend selection to the given screen co-ordinates.
2557 void EDIT_ExtendSel(HWND hwnd
, int x
, int y
)
2559 int bbl
, bel
, bbc
, bec
;
2563 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2565 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2567 dprintf_edit(stddeb
,"EDIT_ExtendSel: x=%d, y=%d\n", x
, y
);
2569 bbl
= es
->SelEndLine
;
2570 bbc
= es
->SelEndCol
;
2571 line
= es
->wtop
+ y
/ es
->txtht
;
2572 if (line
> es
->wlines
)
2574 cp
= EDIT_TextLine(hwnd
, line
);
2575 len
= EDIT_LineLength(hwnd
, line
);
2577 es
->WndRow
= y
/ es
->txtht
;
2578 if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2581 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2586 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2587 es
->SelEndLine
= es
->CurrLine
;
2590 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
|| end
)
2591 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
;
2592 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2593 es
->SelEndCol
= es
->CurrCol
;
2595 bel
= es
->SelEndLine
;
2596 bec
= es
->SelEndCol
;
2598 /* return if no new characters to mark */
2599 if (bbl
== bel
&& bbc
== bec
)
2602 /* put lowest marker first */
2608 if (bbl
== bel
&& bbc
> bec
)
2611 for (y
= bbl
; y
<= bel
; y
++)
2613 if (y
== bbl
&& y
== bel
)
2614 EDIT_WriteSel(hwnd
, y
, bbc
, bec
);
2616 EDIT_WriteSel(hwnd
, y
, bbc
, -1);
2618 EDIT_WriteSel(hwnd
, y
, 0, bec
);
2620 EDIT_WriteSel(hwnd
, y
, 0, -1);
2625 /*********************************************************************
2628 * Display selection by reversing pixels in selected text.
2629 * If end == -1, selection applies to end of line.
2632 void EDIT_WriteSel(HWND hwnd
, int y
, int start
, int end
)
2638 HBRUSH hbrush
, holdbrush
;
2640 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2642 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2644 dprintf_edit(stddeb
,"EDIT_WriteSel: y=%d start=%d end=%d\n", y
, start
,end
);
2645 GetClientRect(hwnd
, &rc
);
2647 /* make sure y is within the window */
2648 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
2651 /* get pointer to text */
2652 cp
= EDIT_TextLine(hwnd
, y
);
2654 /* get length of line if end == -1 */
2656 end
= EDIT_LineLength(hwnd
, y
);
2658 /* For some reason Rectangle, when called with R2_XORPEN filling,
2659 * appears to leave a 2 pixel gap between characters and between
2660 * lines. I have kludged this by adding on two pixels to ecol and
2661 * to the line height in the call to Rectangle.
2663 scol
= EDIT_StrLength(hwnd
, cp
, start
, 0);
2664 if (scol
> rc
.right
) return;
2665 if (scol
< rc
.left
) scol
= rc
.left
;
2666 ecol
= EDIT_StrLength(hwnd
, cp
, end
, 0) + 2; /* ??? */
2667 if (ecol
< rc
.left
) return;
2668 if (ecol
> rc
.right
) ecol
= rc
.right
;
2671 hbrush
= GetStockObject(BLACK_BRUSH
);
2672 holdbrush
= (HBRUSH
)SelectObject(hdc
, (HANDLE
)hbrush
);
2673 olddm
= SetROP2(hdc
, R2_XORPEN
);
2674 Rectangle(hdc
, scol
, y
* es
->txtht
, ecol
, (y
+ 1) * es
->txtht
+ 2);
2675 SetROP2(hdc
, olddm
);
2676 SelectObject(hdc
, (HANDLE
)holdbrush
);
2677 ReleaseDC(hwnd
, hdc
);
2681 /*********************************************************************
2684 * Stop text marking (selection).
2687 void EDIT_StopMarking(HWND hwnd
)
2689 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2691 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2693 TextMarking
= FALSE
;
2694 if (es
->SelBegLine
> es
->SelEndLine
)
2696 swap(&(es
->SelBegLine
), &(es
->SelEndLine
));
2697 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2699 if (es
->SelBegLine
== es
->SelEndLine
&& es
->SelBegCol
> es
->SelEndCol
)
2700 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2704 /*********************************************************************
2705 * EM_GETLINE message function
2708 LONG
EDIT_GetLineMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2712 char *buffer
= (char *)lParam
;
2714 cp
= EDIT_TextLine(hwnd
, wParam
);
2715 cp1
= EDIT_TextLine(hwnd
, wParam
+ 1);
2716 len
= min((int)(cp1
- cp
), (WORD
)(*buffer
));
2717 strncpy(buffer
, cp
, len
);
2723 /*********************************************************************
2724 * EM_GETSEL message function
2727 LONG
EDIT_GetSelMsg(HWND hwnd
)
2730 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2732 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2733 unsigned int *textPtrs
=
2734 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2736 so
= *(textPtrs
+ es
->SelBegLine
) + es
->SelBegCol
;
2737 eo
= *(textPtrs
+ es
->SelEndLine
) + es
->SelEndCol
;
2739 return MAKELONG(so
, eo
);
2743 /*********************************************************************
2744 * EM_REPLACESEL message function
2747 void EDIT_ReplaceSel(HWND hwnd
, LONG lParam
)
2749 EDIT_DeleteSel(hwnd
);
2750 EDIT_InsertText(hwnd
, (char *)PTR_SEG_TO_LIN(lParam
),
2751 strlen((char *)PTR_SEG_TO_LIN(lParam
)));
2752 InvalidateRect(hwnd
, NULL
, TRUE
);
2757 /*********************************************************************
2760 * Insert text at current line and column.
2763 void EDIT_InsertText(HWND hwnd
, char *str
, int len
)
2766 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2768 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2769 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2771 plen
= strlen(text
) + len
;
2772 if (plen
+ 1 > es
->textlen
)
2774 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ len
);
2775 es
->textlen
= plen
+ 1;
2777 memmove(CurrChar
+ len
, CurrChar
, strlen(CurrChar
) + 1);
2778 memcpy(CurrChar
, str
, len
);
2780 EDIT_BuildTextPointers(hwnd
);
2781 es
->PaintBkgd
= TRUE
;
2782 es
->TextChanged
= TRUE
;
2784 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ len
) - text
), &(es
->CurrLine
),
2786 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2787 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2788 es
->CurrCol
, 0) - es
->wleft
;
2792 /*********************************************************************
2793 * EM_LINEFROMCHAR message function
2796 LONG
EDIT_LineFromCharMsg(HWND hwnd
, WORD wParam
)
2799 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2801 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2803 if (wParam
== (WORD
)-1)
2804 return (LONG
)(es
->SelBegLine
);
2806 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2812 /*********************************************************************
2813 * EM_LINEINDEX message function
2816 LONG
EDIT_LineIndexMsg(HWND hwnd
, WORD wParam
)
2818 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2820 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2821 unsigned int *textPtrs
=
2822 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2824 if (wParam
== (WORD
)-1)
2825 wParam
= es
->CurrLine
;
2827 return (LONG
)(*(textPtrs
+ wParam
));
2831 /*********************************************************************
2832 * EM_LINELENGTH message function
2835 LONG
EDIT_LineLengthMsg(HWND hwnd
, WORD wParam
)
2838 int sbl
, sbc
, sel
, sec
;
2839 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2841 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2842 unsigned int *textPtrs
=
2843 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2845 if (wParam
== (WORD
)-1)
2849 sbl
= es
->SelBegLine
;
2850 sbc
= es
->SelBegCol
;
2851 sel
= es
->SelEndLine
;
2852 sec
= es
->SelEndCol
;
2859 if (sbl
== sel
&& sbc
> sec
)
2864 len
= *(textPtrs
+ sbl
+ 1) - *(textPtrs
+ sbl
) - 1;
2865 return len
- sec
- sbc
;
2868 len
= *(textPtrs
+ sel
+ 1) - *(textPtrs
+ sel
) - sec
- 1;
2871 else /* no selection marked */
2873 len
= *(textPtrs
+ es
->CurrLine
+ 1) -
2874 *(textPtrs
+ es
->CurrLine
) - 1;
2878 else /* line number specified */
2880 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2881 len
= *(textPtrs
+ row
+ 1) - *(textPtrs
+ row
);
2887 /*********************************************************************
2888 * WM_SETFONT message function
2891 void EDIT_SetFont(HWND hwnd
, WORD wParam
, LONG lParam
)
2896 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2898 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2899 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
2903 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
2904 GetCharWidth(hdc
, 0, 255, charWidths
);
2905 GetTextMetrics(hdc
, &tm
);
2906 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
2907 SelectObject(hdc
, (HANDLE
)oldfont
);
2908 ReleaseDC(hwnd
, hdc
);
2910 es
->WndRow
= (es
->CurrLine
- es
->wtop
) / es
->txtht
;
2911 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2912 es
->CurrCol
, 0) - es
->wleft
;
2914 InvalidateRect(hwnd
, NULL
, TRUE
);
2915 es
->PaintBkgd
= TRUE
;
2916 if (lParam
) UpdateWindow(hwnd
);
2920 /*********************************************************************
2921 * EDIT_SaveDeletedText
2923 * Save deleted text in deleted text buffer.
2926 void EDIT_SaveDeletedText(HWND hwnd
, char *deltext
, int len
,
2930 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2932 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2934 es
->hDeletedText
= GlobalReAlloc(es
->hDeletedText
, len
, GMEM_MOVEABLE
);
2935 if (!es
->hDeletedText
) return;
2936 text
= (char *)GlobalLock(es
->hDeletedText
);
2937 memcpy(text
, deltext
, len
);
2938 GlobalUnlock(es
->hDeletedText
);
2939 es
->DeletedLength
= len
;
2940 es
->DeletedCurrLine
= line
;
2941 es
->DeletedCurrCol
= col
;
2945 /*********************************************************************
2946 * EDIT_ClearDeletedText
2948 * Clear deleted text buffer.
2951 void EDIT_ClearDeletedText(HWND hwnd
)
2953 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2955 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2957 GlobalFree(es
->hDeletedText
);
2958 es
->hDeletedText
= 0;
2959 es
->DeletedLength
= 0;
2963 /*********************************************************************
2964 * EM_UNDO message function
2967 LONG
EDIT_UndoMsg(HWND hwnd
)
2970 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2972 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2974 if (es
->hDeletedText
)
2976 text
= (char *)GlobalLock(es
->hDeletedText
);
2977 es
->CurrLine
= es
->DeletedCurrLine
;
2978 es
->CurrCol
= es
->DeletedCurrCol
;
2979 EDIT_InsertText(hwnd
, text
, es
->DeletedLength
);
2980 GlobalUnlock(es
->hDeletedText
);
2981 EDIT_ClearDeletedText(hwnd
);
2983 es
->SelBegLine
= es
->CurrLine
;
2984 es
->SelBegCol
= es
->CurrCol
;
2985 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ es
->DeletedLength
) - text
),
2986 &(es
->CurrLine
), &(es
->CurrCol
));
2987 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2988 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2989 es
->CurrCol
, 0) - es
->wleft
;
2990 es
->SelEndLine
= es
->CurrLine
;
2991 es
->SelEndCol
= es
->CurrCol
;
2993 InvalidateRect(hwnd
, NULL
, TRUE
);
3002 /*********************************************************************
3005 * Allocate the specified number of bytes on the specified local heap.
3008 unsigned int EDIT_HeapAlloc(HWND hwnd
, int bytes
)
3010 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3013 ret
= LOCAL_Alloc( wndPtr
->hInstance
, LMEM_FIXED
, bytes
);
3015 printf("EDIT_HeapAlloc: Out of heap-memory\n");
3020 /*********************************************************************
3023 * Return the address of the memory pointed to by the handle.
3026 void *EDIT_HeapAddr(HWND hwnd
, unsigned int handle
)
3028 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3029 return handle
? PTR_SEG_OFF_TO_LIN( wndPtr
->hInstance
, handle
) : 0;
3033 /*********************************************************************
3036 * Reallocate the memory pointed to by the handle.
3039 unsigned int EDIT_HeapReAlloc(HWND hwnd
, unsigned int handle
, int bytes
)
3041 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3043 return LOCAL_ReAlloc( wndPtr
->hInstance
, handle
, bytes
, LMEM_FIXED
);
3047 /*********************************************************************
3050 * Frees the memory pointed to by the handle.
3053 void EDIT_HeapFree(HWND hwnd
, unsigned int handle
)
3055 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3057 LOCAL_Free( wndPtr
->hInstance
, handle
);
3061 /*********************************************************************
3064 * Return the size of the given object on the local heap.
3067 unsigned int EDIT_HeapSize(HWND hwnd
, unsigned int handle
)
3069 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3072 return HEAP_LocalSize((MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2), handle
);
3074 return LOCAL_Size( wndPtr
->hInstance
, handle
);
3078 /*********************************************************************
3079 * EM_SETHANDLE message function
3082 void EDIT_SetHandleMsg(HWND hwnd
, WORD wParam
)
3084 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3086 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3091 es
->textlen
= EDIT_HeapSize(hwnd
, es
->hText
);
3093 es
->wtop
= es
->wleft
= 0;
3094 es
->CurrLine
= es
->CurrCol
= 0;
3095 es
->WndRow
= es
->WndCol
= 0;
3096 es
->TextChanged
= FALSE
;
3098 es
->SelBegLine
= es
->SelBegCol
= 0;
3099 es
->SelEndLine
= es
->SelEndCol
= 0;
3100 dprintf_edit(stddeb
, "EDIT_SetHandleMsg: textlen=%d\n",
3103 EDIT_BuildTextPointers(hwnd
);
3104 es
->PaintBkgd
= TRUE
;
3105 InvalidateRect(hwnd
, NULL
, TRUE
);
3111 /*********************************************************************
3112 * EM_SETTABSTOPS message function
3115 LONG
EDIT_SetTabStopsMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
3117 unsigned short *tabstops
;
3118 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3120 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3122 es
->NumTabStops
= wParam
;
3124 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3125 else if (wParam
== 1)
3127 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3128 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3129 *tabstops
= (unsigned short)lParam
;
3133 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, wParam
);
3134 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3135 memcpy(tabstops
, (unsigned short *)lParam
, wParam
);
3141 /*********************************************************************
3142 * EDIT_CopyToClipboard
3144 * Copy the specified text to the clipboard.
3147 void EDIT_CopyToClipboard(HWND hwnd
)
3153 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3155 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3157 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
3158 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
3159 len
= (int)(bel
- bbl
);
3161 hMem
= GlobalAlloc(GHND
, (DWORD
)(len
+ 1));
3162 lpMem
= GlobalLock(hMem
);
3164 for (i
= 0; i
< len
; i
++)
3168 OpenClipboard(hwnd
);
3170 SetClipboardData(CF_TEXT
, hMem
);
3175 /*********************************************************************
3176 * WM_PASTE message function
3179 void EDIT_PasteMsg(HWND hwnd
)
3184 OpenClipboard(hwnd
);
3185 if (!(hClipMem
= GetClipboardData(CF_TEXT
)))
3187 /* no text in clipboard */
3191 lpClipMem
= GlobalLock(hClipMem
);
3192 EDIT_InsertText(hwnd
, lpClipMem
, strlen(lpClipMem
));
3193 GlobalUnlock(hClipMem
);
3195 InvalidateRect(hwnd
, NULL
, TRUE
);
3200 /*********************************************************************
3204 void swap(int *a
, int *b
)