4 * Copyright David W. Metcalfe, 1994
7 * April 1995 bug fixes (William Magro)
9 static char Copyright[] = "Copyright David W. Metcalfe, 1994";
21 /* #define DEBUG_EDIT */
22 /* #undef DEBUG_EDIT */
26 #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
27 SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
28 GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
30 #define MAXTEXTLEN 30000 /* maximum text buffer length */
31 #define EDITLEN 1024 /* starting length for multi-line control */
32 #define ENTRYLEN 256 /* starting length for single line control */
33 #define GROWLENGTH 64 /* buffers grow by this much */
35 #define HSCROLLDIM (ClientWidth(wndPtr) / 3)
36 /* "line" dimension for horizontal scroll */
40 int wlines
; /* number of lines of text */
41 int wtop
; /* top line that is displayed */
42 int wleft
; /* left pixel that is displayed */
43 unsigned int textlen
; /* text buffer length */
44 int textwidth
; /* width of longest line in pixels */
45 RECT fmtrc
; /* rectangle in which to format text */
46 int txtht
; /* height of text line in pixels */
47 HANDLE hText
; /* handle to text buffer */
48 HANDLE hCharWidths
; /* widths of chars in font */
49 HANDLE hTextPtrs
; /* list of line offsets */
50 HANDLE hBlankLine
; /* to fill blank lines quickly */
51 int CurrCol
; /* current column */
52 int CurrLine
; /* current line */
53 int WndCol
; /* current window column */
54 int WndRow
; /* current window row */
55 BOOL TextChanged
; /* TRUE if text has changed */
56 BOOL PaintBkgd
; /* paint control background */
57 unsigned int MaxTextLen
; /* maximum text buffer length */
58 int SelBegLine
; /* beginning line of selection */
59 int SelBegCol
; /* beginning column of selection */
60 int SelEndLine
; /* ending line of selection */
61 int SelEndCol
; /* ending column of selection */
62 HFONT hFont
; /* handle of current font (if not default) */
63 HANDLE hDeletedText
; /* handle to deleted txet buffer for undo */
64 int DeletedLength
; /* length of deleted text */
65 int DeletedCurrLine
; /* starting line from which text was deleted */
66 int DeletedCurrCol
; /* starting col from which text was deleted */
67 int NumTabStops
; /* number of tab stops in buffer hTabStops */
68 HANDLE hTabStops
; /* handle of tab stops buffer */
69 BOOL HaveFocus
; /* TRUE if this edit has the focus */
73 #define ClientWidth(wndPtr) \
74 (wndPtr->rectClient.right > wndPtr->rectClient.left ? \
75 wndPtr->rectClient.right - wndPtr->rectClient.left : 0)
76 #define ClientHeight(wndPtr, es) \
77 (wndPtr->rectClient.bottom > wndPtr->rectClient.top ? \
78 (wndPtr->rectClient.bottom - wndPtr->rectClient.top) / es->txtht : 0)
79 #define EditBufLen(wndPtr) (wndPtr->dwStyle & ES_MULTILINE \
81 #define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol)
82 #define SelMarked(es) (es->SelBegLine != 0 || es->SelBegCol != 0 || \
83 es->SelEndLine != 0 || es->SelEndCol != 0)
84 #define ROUNDUP(numer, denom) (((numer) % (denom)) \
85 ? ((((numer) + (denom)) / (denom)) * (denom)) \
88 /* macros to access window styles */
89 #define IsAutoVScroll() (wndPtr->dwStyle & ES_AUTOVSCROLL)
90 #define IsAutoHScroll() (wndPtr->dwStyle & ES_AUTOHSCROLL)
91 #define IsMultiLine() (wndPtr->dwStyle & ES_MULTILINE)
92 #define IsVScrollBar() (wndPtr->dwStyle & WS_VSCROLL)
93 #define IsHScrollBar() (wndPtr->dwStyle & WS_HSCROLL)
95 /* internal variables */
96 static BOOL TextMarking
; /* TRUE if text marking in progress */
97 static BOOL ButtonDown
; /* TRUE if left mouse button down */
98 static int ButtonRow
; /* row in text buffer when button pressed */
99 static int ButtonCol
; /* col in text buffer when button pressed */
102 LONG
EditWndProc(HWND hWnd
, WORD uMsg
, WORD wParam
, LONG lParam
);
103 long EDIT_NCCreateMsg(HWND hwnd
, LONG lParam
);
104 long EDIT_CreateMsg(HWND hwnd
, LONG lParam
);
105 void EDIT_ClearTextPointers(HWND hwnd
);
106 void EDIT_BuildTextPointers(HWND hwnd
);
107 void EDIT_ModTextPointers(HWND hwnd
, int lineno
, int var
);
108 void EDIT_PaintMsg(HWND hwnd
);
109 HANDLE
EDIT_GetTextLine(HWND hwnd
, int selection
);
110 char *EDIT_TextLine(HWND hwnd
, int sel
);
111 int EDIT_StrLength(HWND hwnd
, unsigned char *str
, int len
, int pcol
);
112 int EDIT_LineLength(HWND hwnd
, int num
);
113 void EDIT_WriteTextLine(HWND hwnd
, RECT
*rc
, int y
);
114 void EDIT_WriteText(HWND hwnd
, char *lp
, int off
, int len
, int row
,
115 int col
, RECT
*rc
, BOOL blank
, BOOL reverse
);
116 HANDLE
EDIT_GetStr(HWND hwnd
, char *lp
, int off
, int len
, int *diff
);
117 void EDIT_CharMsg(HWND hwnd
, WORD wParam
);
118 void EDIT_KeyTyped(HWND hwnd
, short ch
);
119 int EDIT_CharWidth(HWND hwnd
, short ch
, int pcol
);
120 int EDIT_GetNextTabStop(HWND hwnd
, int pcol
);
121 void EDIT_Forward(HWND hwnd
);
122 void EDIT_Downward(HWND hwnd
);
123 void EDIT_Upward(HWND hwnd
);
124 void EDIT_Backward(HWND hwnd
);
125 void EDIT_End(HWND hwnd
);
126 void EDIT_Home(HWND hwnd
);
127 void EDIT_StickEnd(HWND hwnd
);
128 void EDIT_KeyDownMsg(HWND hwnd
, WORD wParam
);
129 void EDIT_KeyHScroll(HWND hwnd
, WORD opt
);
130 void EDIT_KeyVScrollLine(HWND hwnd
, WORD opt
);
131 void EDIT_KeyVScrollPage(HWND hwnd
, WORD opt
);
132 void EDIT_KeyVScrollDoc(HWND hwnd
, WORD opt
);
133 int EDIT_ComputeVScrollPos(HWND hwnd
);
134 int EDIT_ComputeHScrollPos(HWND hwnd
);
135 void EDIT_DelKey(HWND hwnd
);
136 void EDIT_VScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
137 void EDIT_VScrollLine(HWND hwnd
, WORD opt
);
138 void EDIT_VScrollPage(HWND hwnd
, WORD opt
);
139 void EDIT_HScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
140 void EDIT_SizeMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
141 void EDIT_LButtonDownMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
142 void EDIT_MouseMoveMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
143 int EDIT_PixelToChar(HWND hwnd
, int row
, int *pixel
);
144 LONG
EDIT_SetTextMsg(HWND hwnd
, LONG lParam
);
145 void EDIT_ClearText(HWND hwnd
);
146 void EDIT_SetSelMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
147 void EDIT_GetLineCol(HWND hwnd
, int off
, int *line
, int *col
);
148 void EDIT_DeleteSel(HWND hwnd
);
149 void EDIT_ClearSel(HWND hwnd
);
150 int EDIT_TextLineNumber(HWND hwnd
, char *lp
);
151 void EDIT_SetAnchor(HWND hwnd
, int row
, int col
);
152 void EDIT_ExtendSel(HWND hwnd
, INT x
, INT y
);
153 void EDIT_WriteSel(HWND hwnd
, int y
, int start
, int end
);
154 void EDIT_StopMarking(HWND hwnd
);
155 LONG
EDIT_GetLineMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
156 LONG
EDIT_GetSelMsg(HWND hwnd
);
157 void EDIT_ReplaceSel(HWND hwnd
, LONG lParam
);
158 void EDIT_InsertText(HWND hwnd
, char *str
, int len
);
159 LONG
EDIT_LineFromCharMsg(HWND hwnd
, WORD wParam
);
160 LONG
EDIT_LineIndexMsg(HWND hwnd
, WORD wParam
);
161 LONG
EDIT_LineLengthMsg(HWND hwnd
, WORD wParam
);
162 void EDIT_SetFont(HWND hwnd
, WORD wParam
, LONG lParam
);
163 void EDIT_SaveDeletedText(HWND hwnd
, char *deltext
, int len
, int line
,
165 void EDIT_ClearDeletedText(HWND hwnd
);
166 LONG
EDIT_UndoMsg(HWND hwnd
);
167 unsigned int EDIT_HeapAlloc(HWND hwnd
, int bytes
);
168 void *EDIT_HeapAddr(HWND hwnd
, unsigned int handle
);
169 unsigned int EDIT_HeapReAlloc(HWND hwnd
, unsigned int handle
, int bytes
);
170 void EDIT_HeapFree(HWND hwnd
, unsigned int handle
);
171 unsigned int EDIT_HeapSize(HWND hwnd
, unsigned int handle
);
172 void EDIT_SetHandleMsg(HWND hwnd
, WORD wParam
);
173 LONG
EDIT_SetTabStopsMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
174 void EDIT_CopyToClipboard(HWND hwnd
);
175 void EDIT_PasteMsg(HWND hwnd
);
176 void swap(int *a
, int *b
);
179 LONG
EditWndProc(HWND hwnd
, WORD uMsg
, WORD wParam
, LONG lParam
)
184 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
186 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
190 lResult
= es
->hDeletedText
;
193 case EM_EMPTYUNDOBUFFER
:
194 EDIT_ClearDeletedText(hwnd
);
198 fprintf(stdnimp
,"edit: EM_FMTLINES message received\n");
205 case EM_GETFIRSTVISIBLELINE
:
215 lResult
= EDIT_GetLineMsg(hwnd
, wParam
, lParam
);
220 case EM_GETLINECOUNT
:
222 lResult
= es
->wlines
;
228 lResult
= es
->TextChanged
;
231 case EM_GETPASSWORDCHAR
:
232 fprintf(stdnimp
,"edit: cannot process EM_GETPASSWORDCHAR message\n");
236 GetWindowRect(hwnd
, (LPRECT
)PTR_SEG_TO_LIN(lParam
));
240 lResult
= EDIT_GetSelMsg(hwnd
);
243 case EM_GETWORDBREAKPROC
:
244 fprintf(stdnimp
,"edit: cannot process EM_GETWORDBREAKPROC message\n");
249 es
->MaxTextLen
= wParam
;
250 else if (IsMultiLine())
251 es
->MaxTextLen
= 65535;
253 es
->MaxTextLen
= 32767;
256 case EM_LINEFROMCHAR
:
257 lResult
= EDIT_LineFromCharMsg(hwnd
, wParam
);
262 lResult
= EDIT_LineIndexMsg(hwnd
, wParam
);
268 lResult
= EDIT_LineLengthMsg(hwnd
, wParam
);
272 fprintf(stdnimp
,"edit: cannot process EM_LINESCROLL message\n");
277 EDIT_ReplaceSel(hwnd
, lParam
);
278 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
284 EDIT_SetHandleMsg(hwnd
, wParam
);
285 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
290 es
->TextChanged
= wParam
;
293 case EM_SETPASSWORDCHAR
:
294 fprintf(stdnimp
,"edit: cannot process EM_SETPASSWORDCHAR message\n");
298 fprintf(stdnimp
,"edit: cannot process EM_SETREADONLY message\n");
303 fprintf(stdnimp
,"edit: cannot process EM_SETRECT(NP) message\n");
308 EDIT_SetSelMsg(hwnd
, wParam
, lParam
);
309 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
314 lResult
= EDIT_SetTabStopsMsg(hwnd
, wParam
, lParam
);
317 case EM_SETWORDBREAKPROC
:
318 fprintf(stdnimp
,"edit: cannot process EM_SETWORDBREAKPROC message\n");
323 lResult
= EDIT_UndoMsg(hwnd
);
324 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
329 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
332 EDIT_CharMsg(hwnd
, wParam
);
336 EDIT_CopyToClipboard(hwnd
);
341 lResult
= EDIT_CreateMsg(hwnd
, lParam
);
345 EDIT_CopyToClipboard(hwnd
);
346 EDIT_DeleteSel(hwnd
);
350 EDIT_HeapFree(hwnd
, es
->hTextPtrs
);
351 EDIT_HeapFree(hwnd
, es
->hCharWidths
);
352 EDIT_HeapFree(hwnd
, es
->hText
);
353 EDIT_HeapFree(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
357 InvalidateRect(hwnd
, NULL
, FALSE
);
361 textPtr
= EDIT_HeapAddr(hwnd
, es
->hText
);
362 if ((int)wParam
> (len
= strlen(textPtr
)))
364 strcpy((char *)PTR_SEG_TO_LIN(lParam
), textPtr
);
365 lResult
= (DWORD
)len
;
371 case WM_GETTEXTLENGTH
:
372 textPtr
= EDIT_HeapAddr(hwnd
, es
->hText
);
373 lResult
= (DWORD
)strlen(textPtr
);
377 EDIT_HScrollMsg(hwnd
, wParam
, lParam
);
381 EDIT_KeyDownMsg(hwnd
, wParam
);
385 es
->HaveFocus
= FALSE
;
387 if (SelMarked(es
)) EDIT_ClearSel(hwnd
);
388 NOTIFY_PARENT(hwnd
, EN_KILLFOCUS
);
395 EDIT_LButtonDownMsg(hwnd
, wParam
, lParam
);
396 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
401 if (GetCapture() != hwnd
) break;
405 EDIT_StopMarking(hwnd
);
410 EDIT_MouseMoveMsg(hwnd
, wParam
, lParam
);
418 lResult
= EDIT_NCCreateMsg(hwnd
, lParam
);
430 es
->HaveFocus
= TRUE
;
431 CreateCaret(hwnd
, 0, 2, es
->txtht
);
432 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
434 NOTIFY_PARENT(hwnd
, EN_SETFOCUS
);
439 EDIT_SetFont(hwnd
, wParam
, lParam
);
440 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
445 dprintf_edit(stddeb
, "WM_SETREDRAW: hwnd=%d, wParam=%x\n",
451 EDIT_SetTextMsg(hwnd
, lParam
);
455 EDIT_SizeMsg(hwnd
, wParam
, lParam
);
460 EDIT_VScrollMsg(hwnd
, wParam
, lParam
);
464 lResult
= DefWindowProc(hwnd
, uMsg
, wParam
, lParam
);
472 /*********************************************************************
473 * WM_NCCREATE message function
476 long EDIT_NCCreateMsg(HWND hwnd
, LONG lParam
)
478 CREATESTRUCT
*createStruct
= (CREATESTRUCT
*)PTR_SEG_TO_LIN(lParam
);
479 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
481 unsigned int *textPtrs
;
484 /* store pointer to local or global heap in window structure so that */
485 /* EDITSTATE structure itself can be stored on local heap */
487 if (HEAP_LocalFindHeap(createStruct
->hInstance
)!=NULL
)
488 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
489 &HEAP_LocalFindHeap(createStruct
->hInstance
)->free_list
;
492 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
493 GlobalLock(createStruct
->hInstance
);
494 /* GlobalUnlock(createStruct->hInstance); */
497 /* allocate space for state variable structure */
498 (HANDLE
)(*(wndPtr
->wExtra
)) = EDIT_HeapAlloc(hwnd
, sizeof(EDITSTATE
));
499 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
500 es
->hTextPtrs
= EDIT_HeapAlloc(hwnd
, sizeof(int));
501 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
502 es
->hCharWidths
= EDIT_HeapAlloc(hwnd
, 256 * sizeof(short));
504 /* --- text buffer */
505 es
->MaxTextLen
= MAXTEXTLEN
+ 1;
506 if (!(createStruct
->lpszName
))
508 es
->textlen
= EditBufLen(wndPtr
) + 1;
509 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
510 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
511 memset(text
, 0, es
->textlen
+ 2);
514 EDIT_ClearTextPointers(hwnd
);
515 if(IsMultiLine()) strcpy(text
, "\r\n");
516 EDIT_BuildTextPointers(hwnd
);
520 char *windowName
= (char *)PTR_SEG_TO_LIN( createStruct
->lpszName
);
521 if (strlen(windowName
) < EditBufLen(wndPtr
))
523 es
->textlen
= EditBufLen(wndPtr
) + 1;
524 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
525 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
526 strcpy(text
, windowName
);
527 if(IsMultiLine()) strcat(text
, "\r\n");
529 *(text
+ es
->textlen
) = '\0';
533 es
->hText
= EDIT_HeapAlloc(hwnd
, strlen(windowName
) + 4);
534 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
535 strcpy(text
, windowName
);
536 if(IsMultiLine()) strcat(text
, "\r\n");
537 es
->textlen
= strlen(windowName
) + 3;
538 *(text
+ es
->textlen
) = '\0';
540 *(text
+ es
->textlen
+ 1) = '\0';
541 EDIT_BuildTextPointers(hwnd
);
544 /* ES_AUTOVSCROLL and ES_AUTOHSCROLL are automatically applied if */
545 /* the corresponding WS_* style is set */
546 if (createStruct
->style
& WS_VSCROLL
)
547 wndPtr
->dwStyle
|= ES_AUTOVSCROLL
;
548 if (createStruct
->style
& WS_HSCROLL
)
549 wndPtr
->dwStyle
|= ES_AUTOHSCROLL
;
551 /* remove the WS_CAPTION style if it has been set - this is really a */
552 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
553 if (wndPtr
->dwStyle
& WS_BORDER
&& wndPtr
->dwStyle
& WS_DLGFRAME
)
554 wndPtr
->dwStyle
^= WS_DLGFRAME
;
560 /*********************************************************************
561 * WM_CREATE message function
564 long EDIT_CreateMsg(HWND hwnd
, LONG lParam
)
567 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
569 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
575 /* initialize state variable structure */
578 /* --- char width array */
579 /* only initialise chars <= 32 as X returns strange widths */
580 /* for other chars */
581 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
582 memset(charWidths
, 0, 256 * sizeof(short));
583 GetCharWidth(hdc
, 32, 254, &charWidths
[32]);
585 /* --- other structure variables */
586 GetTextMetrics(hdc
, &tm
);
587 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
588 es
->wtop
= es
->wleft
= 0;
589 es
->CurrCol
= es
->CurrLine
= 0;
590 es
->WndCol
= es
->WndRow
= 0;
591 es
->TextChanged
= FALSE
;
592 es
->SelBegLine
= es
->SelBegCol
= 0;
593 es
->SelEndLine
= es
->SelEndCol
= 0;
595 es
->hDeletedText
= 0;
596 es
->DeletedLength
= 0;
598 es
->hTabStops
= EDIT_HeapAlloc(hwnd
, sizeof(int));
600 /* allocate space for a line full of blanks to speed up */
602 es
->hBlankLine
= EDIT_HeapAlloc(hwnd
, (ClientWidth(wndPtr
) /
603 charWidths
[32]) + 2);
604 text
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
605 memset(text
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
607 /* set up text cursor for edit class */
608 CLASS_FindClassByName("EDIT", 0, &classPtr
);
609 classPtr
->wc
.hCursor
= LoadCursor(0, IDC_IBEAM
);
611 /* paint background on first WM_PAINT */
612 es
->PaintBkgd
= TRUE
;
614 ReleaseDC(hwnd
, hdc
);
619 /*********************************************************************
620 * EDIT_ClearTextPointers
622 * Clear and initialize text line pointer array.
625 void EDIT_ClearTextPointers(HWND hwnd
)
627 unsigned int *textPtrs
;
628 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
630 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
632 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
, sizeof(int));
633 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
638 /*********************************************************************
639 * EDIT_BuildTextPointers
641 * Build array of pointers to text lines.
644 #define INITLINES 100
646 void EDIT_BuildTextPointers(HWND hwnd
)
648 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
650 int incrs
= INITLINES
;
651 unsigned int off
, len
;
653 unsigned int *textPtrs
;
656 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
657 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
658 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
659 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
661 es
->textwidth
= es
->wlines
= 0;
664 /* advance through text buffer */
667 /* increase size of text pointer array */
668 if (incrs
== INITLINES
)
671 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
,
672 (es
->wlines
+ INITLINES
) * sizeof(int));
673 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
675 off
= (unsigned int)(cp
- text
); /* offset of beginning of line */
676 *(textPtrs
+ es
->wlines
) = off
;
681 /* advance through current line */
682 while (*cp
&& *cp
!= '\n')
684 len
+= EDIT_CharWidth(hwnd
, (BYTE
)*cp
, len
);
685 /* width of line in pixels */
688 es
->textwidth
= max(es
->textwidth
, len
);
690 cp
++; /* skip '\n' */
693 off
= (unsigned int)(cp
- text
);
694 *(textPtrs
+ es
->wlines
) = off
;
698 /*********************************************************************
699 * EDIT_ModTextPointers
701 * Modify text pointers from a specified position.
704 void EDIT_ModTextPointers(HWND hwnd
, int lineno
, int var
)
706 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
708 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
709 unsigned int *textPtrs
=
710 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
712 while (lineno
< es
->wlines
)
713 *(textPtrs
+ lineno
++) += var
;
717 /*********************************************************************
718 * WM_PAINT message function
721 void EDIT_PaintMsg(HWND hwnd
)
727 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
729 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
731 hdc
= BeginPaint(hwnd
, &ps
);
734 dprintf_edit(stddeb
,"WM_PAINT: rc=(%d,%d), (%d,%d)\n", rc
.left
, rc
.top
,
735 rc
.right
, rc
.bottom
);
738 FillWindow(GetParent(hwnd
), hwnd
, hdc
, CTLCOLOR_EDIT
);
740 for (y
= (rc
.top
/ es
->txtht
); y
<= (rc
.bottom
/ es
->txtht
); y
++)
742 if (y
< (IsMultiLine() ? es
->wlines
: 1) - es
->wtop
)
743 EDIT_WriteTextLine(hwnd
, &rc
, y
+ es
->wtop
);
750 /*********************************************************************
753 * Get a copy of the text in the specified line.
756 HANDLE
EDIT_GetTextLine(HWND hwnd
, int selection
)
763 dprintf_edit(stddeb
,"GetTextLine %d\n", selection
);
764 cp
= cp1
= EDIT_TextLine(hwnd
, selection
);
765 /* advance through line */
766 while (*cp
&& *cp
!= '\r')
772 /* store selected line and return handle */
773 hLine
= EDIT_HeapAlloc(hwnd
, len
+ 6);
774 line
= (char *)EDIT_HeapAddr(hwnd
, hLine
);
775 memmove(line
, cp1
, len
);
781 /*********************************************************************
784 * Return a pointer to the text in the specified line.
787 char *EDIT_TextLine(HWND hwnd
, int sel
)
789 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
791 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
792 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
793 unsigned int *textPtrs
=
794 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
796 if(sel
>es
->wlines
)return NULL
;
797 return (text
+ *(textPtrs
+ sel
));
801 /*********************************************************************
804 * Return length of string _str_ of length _len_ characters in pixels.
805 * The current column offset in pixels _pcol_ is required to calculate
806 * the width of a tab.
809 int EDIT_StrLength(HWND hwnd
, unsigned char *str
, int len
, int pcol
)
813 for (i
= 0; i
< len
; i
++)
814 plen
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(str
+ i
)), pcol
+ plen
);
816 dprintf_edit(stddeb
,"EDIT_StrLength: returning %d\n", plen
);
821 /*********************************************************************
824 * Return length of line _num_ in characters.
827 int EDIT_LineLength(HWND hwnd
, int num
)
829 char *cp
= EDIT_TextLine(hwnd
, num
);
833 cp1
= strchr(cp
, '\r');
834 return cp1
? (int)(cp1
- cp
) : strlen(cp
);
838 /*********************************************************************
841 * Write the line of text at offset _y_ in text buffer to a window.
844 void EDIT_WriteTextLine(HWND hwnd
, RECT
*rect
, int y
)
851 int sbl
, sel
, sbc
, sec
;
853 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
855 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
857 /* initialize rectangle if NULL, else copy */
861 GetClientRect(hwnd
, &rc
);
863 dprintf_edit(stddeb
,"WriteTextLine %d\n", y
);
865 /* make sure y is inside the window */
866 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
868 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is not a displayed line\n", y
);
872 /* make sure rectangle is within window */
873 if (rc
.left
>= ClientWidth(wndPtr
) - 1)
875 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.left (%d) is greater than right edge\n",
881 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.right (%d) is less than left edge\n",
885 if (y
- es
->wtop
< (rc
.top
/ es
->txtht
) ||
886 y
- es
->wtop
> (rc
.bottom
/ es
->txtht
))
888 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is outside window\n", y
);
892 /* get the text and length of line */
893 if ((hLine
= EDIT_GetTextLine(hwnd
, y
)) == 0)
895 lp
= (unsigned char *)EDIT_HeapAddr(hwnd
, hLine
);
896 lnlen
= EDIT_StrLength(hwnd
, lp
, strlen(lp
), 0);
899 /* build the line to display */
900 if (lnlen
< (es
->wleft
+ rc
.left
))
914 lnlen
= lnlen1
- off
;
916 len
= min(lnlen
, rc
.right
- rc
.left
);
920 sbl
= es
->SelBegLine
;
921 sel
= es
->SelEndLine
;
925 /* put lowest marker first */
931 if (sbl
== sel
&& sbc
> sec
)
934 if (y
< sbl
|| y
> sel
)
935 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
937 else if (y
> sbl
&& y
< sel
)
938 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
942 col
= EDIT_StrLength(hwnd
, lp
, sbc
, 0);
943 if (col
> (es
->wleft
+ rc
.left
))
945 len
= min(col
- off
, rc
.right
- off
);
946 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
947 rc
.left
, &rc
, FALSE
, FALSE
);
952 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
953 if (col
< (es
->wleft
+ rc
.right
))
955 len
= min(col
- off
, rc
.right
- off
);
956 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
957 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
959 len
= min(lnlen
- off
, rc
.right
- off
);
960 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
961 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
965 len
= min(lnlen
- off
, rc
.right
- off
);
966 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
967 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
972 len
= min(lnlen
- off
, rc
.right
- off
);
973 if (col
< (es
->wleft
+ rc
.right
))
974 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
975 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
980 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
981 if (col
< (es
->wleft
+ rc
.right
))
983 len
= min(col
- off
, rc
.right
- off
);
984 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
985 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
987 len
= min(lnlen
- off
, rc
.right
- off
);
988 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
989 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
994 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
997 EDIT_HeapFree(hwnd
, hLine
);
1001 /*********************************************************************
1004 * Write text to a window
1006 * off - offset in text line (in pixels)
1007 * len - length from off (in pixels)
1008 * row - line in window
1009 * col - column in window
1010 * rc - rectangle in which to display line
1011 * blank - blank remainder of line?
1012 * reverse - reverse color of line?
1015 void EDIT_WriteText(HWND hwnd
, char *lp
, int off
, int len
, int row
,
1016 int col
, RECT
*rc
, BOOL blank
, BOOL reverse
)
1020 char *str
, *cp
, *cp1
;
1021 int diff
=0, num_spaces
, tabwidth
, scol
;
1023 COLORREF oldTextColor
, oldBkgdColor
;
1025 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1027 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1028 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1029 char *blanks
= (char *)EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1031 dprintf_edit(stddeb
,"EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp
, off
, len
, row
, col
, reverse
);
1040 hStr
= EDIT_GetStr(hwnd
, lp
, off
, len
, &diff
);
1041 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1042 hrgnClip
= CreateRectRgnIndirect(rc
);
1043 SelectClipRgn(hdc
, hrgnClip
);
1046 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
1048 SendMessage(GetParent(hwnd
), WM_CTLCOLOR
, (WORD
)hdc
,
1049 MAKELPARAM(hwnd
, CTLCOLOR_EDIT
));
1053 oldBkgdColor
= GetBkColor(hdc
);
1054 oldTextColor
= GetTextColor(hdc
);
1055 SetBkColor(hdc
, oldTextColor
);
1056 SetTextColor(hdc
, oldBkgdColor
);
1059 if (strlen(blanks
) < (ClientWidth(wndPtr
) / charWidths
[32]) + 2)
1061 es
->hBlankLine
= EDIT_HeapReAlloc(hwnd
, es
->hBlankLine
,
1062 (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1063 blanks
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1064 memset(blanks
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1067 if (!(cp
= strchr(str
, VK_TAB
)))
1068 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, strlen(str
));
1071 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, (int)(cp
- str
));
1072 scol
= EDIT_StrLength(hwnd
, str
, (int)(cp
- str
), 0);
1073 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1074 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1075 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1079 while ((cp1
= strchr(cp
, VK_TAB
)))
1081 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, (int)(cp1
- cp
));
1082 scol
+= EDIT_StrLength(hwnd
, cp
, (int)(cp1
- cp
), scol
);
1083 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1084 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1085 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1090 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, strlen(cp
));
1095 SetBkColor(hdc
, oldBkgdColor
);
1096 SetTextColor(hdc
, oldTextColor
);
1099 /* blank out remainder of line if appropriate */
1102 if ((rc
->right
- col
) > len
)
1104 num_spaces
= (rc
->right
- col
- len
) / charWidths
[32];
1105 TextOut(hdc
, col
+ len
, row
* es
->txtht
, blanks
, num_spaces
);
1110 SelectObject(hdc
, (HANDLE
)oldfont
);
1112 EDIT_HeapFree(hwnd
, hStr
);
1113 ReleaseDC(hwnd
, hdc
);
1117 /*********************************************************************
1120 * Return sub-string starting at pixel _off_ of length _len_ pixels.
1121 * If _off_ is part way through a character, the negative offset of
1122 * the beginning of the character is returned in _diff_, else _diff_
1126 HANDLE
EDIT_GetStr(HWND hwnd
, char *lp
, int off
, int len
, int *diff
)
1130 int ch
= 0, i
= 0, j
, s_i
=0;
1133 dprintf_edit(stddeb
,"EDIT_GetStr lp='%s' off=%d len=%d\n", lp
, off
, len
);
1135 if (off
< 0) off
= 0;
1139 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1142 /* if stepped past _off_, go back a character */
1150 while (i
< len
+ off
)
1152 if (*(lp
+ ch
) == '\r' || *(lp
+ ch
) == '\n')
1154 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1158 hStr
= EDIT_HeapAlloc(hwnd
, ch
- ch1
+ 3);
1159 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1160 for (i
= ch1
, j
= 0; i
< ch
; i
++, j
++)
1163 dprintf_edit(stddeb
,"EDIT_GetStr: returning %s\n", str
);
1168 /*********************************************************************
1169 * WM_CHAR message function
1172 void EDIT_CharMsg(HWND hwnd
, WORD wParam
)
1174 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1176 dprintf_edit(stddeb
,"EDIT_CharMsg: wParam=%c\n", (char)wParam
);
1185 EDIT_KeyTyped(hwnd
, wParam
);
1191 EDIT_KeyTyped(hwnd
, wParam
);
1195 if (wParam
>= 20 && wParam
<= 254 && wParam
!= 127 )
1196 EDIT_KeyTyped(hwnd
, wParam
);
1202 /*********************************************************************
1205 * Process keystrokes that produce displayable characters.
1208 void EDIT_KeyTyped(HWND hwnd
, short ch
)
1210 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1212 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1213 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1216 BOOL FullPaint
= FALSE
;
1218 dprintf_edit(stddeb
,"EDIT_KeyTyped: ch=%c\n", (char)ch
);
1220 /* delete selected text (if any) */
1222 EDIT_DeleteSel(hwnd
);
1224 /* currchar must be assigned after deleting the selection */
1225 currchar
= CurrChar
;
1227 /* test for typing at end of maximum buffer size */
1228 if (currchar
== text
+ es
->MaxTextLen
)
1230 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1234 if (*currchar
== '\0' && IsMultiLine())
1236 /* insert a newline at end of text */
1238 *(currchar
+ 1) = '\n';
1239 *(currchar
+ 2) = '\0';
1240 EDIT_BuildTextPointers(hwnd
);
1243 /* insert the typed character */
1244 if (text
[es
->textlen
- 1] != '\0')
1246 /* current text buffer is full */
1247 if (es
->textlen
== es
->MaxTextLen
)
1249 /* text buffer is at maximum size */
1250 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1254 /* increase the text buffer size */
1255 es
->textlen
+= GROWLENGTH
;
1256 /* but not above maximum size */
1257 if (es
->textlen
> es
->MaxTextLen
)
1258 es
->textlen
= es
->MaxTextLen
;
1259 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ 2);
1261 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1262 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1263 text
[es
->textlen
- 1] = '\0';
1264 currchar
= CurrChar
;
1266 /* make space for new character and put char in buffer */
1269 memmove(currchar
+ 2, currchar
, strlen(currchar
) + 1);
1271 *(currchar
+ 1) = '\n';
1272 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, 2);
1276 memmove(currchar
+ 1, currchar
, strlen(currchar
) + 1);
1278 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, 1);
1280 es
->TextChanged
= TRUE
;
1281 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1283 /* re-adjust textwidth, if necessary, and redraw line */
1285 if (IsMultiLine() && es
->wlines
> 1)
1287 es
->textwidth
= max(es
->textwidth
,
1288 EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
1289 (int)(EDIT_TextLine(hwnd
, es
->CurrLine
+ 1) -
1290 EDIT_TextLine(hwnd
, es
->CurrLine
)), 0));
1293 es
->textwidth
= max(es
->textwidth
,
1294 EDIT_StrLength(hwnd
, text
, strlen(text
), 0));
1301 EDIT_BuildTextPointers(hwnd
);
1305 /* invalidate rest of window */
1306 GetClientRect(hwnd
, &rc
);
1308 rc
.top
= es
->WndRow
* es
->txtht
;
1309 InvalidateRect(hwnd
, &rc
, FALSE
);
1311 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1314 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1318 /* test end of window */
1319 if (es
->WndCol
>= ClientWidth(wndPtr
) -
1320 EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
))
1322 /* TODO:- Word wrap to be handled here */
1324 /* if (!(currchar == text + es->MaxTextLen - 2)) */
1325 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1327 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
);
1329 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ es
->WndRow
);
1330 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1332 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1336 /*********************************************************************
1339 * Return the width of the given character in pixels.
1340 * The current column offset in pixels _pcol_ is required to calculate
1341 * the width of a tab.
1344 int EDIT_CharWidth(HWND hwnd
, short ch
, int pcol
)
1346 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1348 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1349 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1352 return (charWidths
[ch
]);
1354 return (EDIT_GetNextTabStop(hwnd
, pcol
) - pcol
);
1358 /*********************************************************************
1359 * EDIT_GetNextTabStop
1361 * Return the next tab stop beyond _pcol_.
1364 int EDIT_GetNextTabStop(HWND hwnd
, int pcol
)
1367 int baseUnitWidth
= LOWORD(GetDialogBaseUnits());
1368 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1370 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1371 unsigned short *tabstops
= EDIT_HeapAddr(hwnd
, es
->hTabStops
);
1373 if (es
->NumTabStops
== 0)
1374 return ROUNDUP(pcol
, 8 * baseUnitWidth
);
1375 else if (es
->NumTabStops
== 1)
1376 return ROUNDUP(pcol
, *tabstops
* baseUnitWidth
/ 4);
1379 for (i
= 0; i
< es
->NumTabStops
; i
++)
1381 if (*(tabstops
+ i
) * baseUnitWidth
/ 4 >= pcol
)
1382 return (*(tabstops
+ i
) * baseUnitWidth
/ 4);
1389 /*********************************************************************
1392 * Cursor right key: move right one character position.
1395 void EDIT_Forward(HWND hwnd
)
1397 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1399 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1401 if (*CurrChar
== '\0')
1404 if (*CurrChar
== '\r')
1406 if (es
->CurrLine
< (es
->wlines
- 1))
1409 EDIT_Downward(hwnd
);
1414 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1416 if (es
->WndCol
>= ClientWidth(wndPtr
))
1417 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1423 /*********************************************************************
1426 * Cursor down key: move down one line.
1429 void EDIT_Downward(HWND hwnd
)
1431 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1433 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1435 dprintf_edit(stddeb
,"EDIT_Downward: WndRow=%d, wtop=%d, wlines=%d\n",
1436 es
->WndRow
, es
->wtop
, es
->wlines
);
1438 if (IsMultiLine() && (es
->WndRow
+ es
->wtop
+ 1 < es
->wlines
))
1441 if (es
->WndRow
== ClientHeight(wndPtr
, es
) - 1)
1444 EDIT_KeyVScrollLine(hwnd
, SB_LINEDOWN
);
1448 EDIT_StickEnd(hwnd
);
1453 /*********************************************************************
1456 * Cursor up key: move up one line.
1459 void EDIT_Upward(HWND hwnd
)
1461 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1463 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1465 if (IsMultiLine() && es
->CurrLine
!= 0)
1468 if (es
->WndRow
== 0)
1471 EDIT_KeyVScrollLine(hwnd
, SB_LINEUP
);
1475 EDIT_StickEnd(hwnd
);
1480 /*********************************************************************
1483 * Cursor left key: move left one character position.
1486 void EDIT_Backward(HWND hwnd
)
1488 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1490 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1495 if (*CurrChar
== VK_TAB
)
1496 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
),
1497 EDIT_StrLength(hwnd
,
1498 EDIT_TextLine(hwnd
, es
->CurrLine
),
1501 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), 0);
1503 EDIT_KeyHScroll(hwnd
, SB_LINEUP
);
1505 else if (IsMultiLine() && es
->CurrLine
!= 0)
1513 /*********************************************************************
1516 * End key: move to end of line.
1519 void EDIT_End(HWND hwnd
)
1521 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1523 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1525 while (*CurrChar
&& *CurrChar
!= '\r')
1527 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1531 if (es
->WndCol
>= ClientWidth(wndPtr
))
1533 es
->wleft
= es
->WndCol
- ClientWidth(wndPtr
) + HSCROLLDIM
;
1534 es
->WndCol
-= es
->wleft
;
1535 InvalidateRect(hwnd
, NULL
, FALSE
);
1541 /*********************************************************************
1544 * Home key: move to beginning of line.
1547 void EDIT_Home(HWND hwnd
)
1549 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1551 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1553 es
->CurrCol
= es
->WndCol
= 0;
1557 InvalidateRect(hwnd
, NULL
, FALSE
);
1563 /*********************************************************************
1566 * Stick the cursor to the end of the line.
1569 void EDIT_StickEnd(HWND hwnd
)
1571 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1573 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1574 int len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
1575 char *cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
1578 es
->CurrCol
= min(len
, es
->CurrCol
);
1579 es
->WndCol
= min(EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
, es
->WndCol
);
1580 currpel
= EDIT_StrLength(hwnd
, cp
, es
->CurrCol
, 0);
1582 if (es
->wleft
> currpel
)
1584 es
->wleft
= max(0, currpel
- 20);
1585 es
->WndCol
= currpel
- es
->wleft
;
1588 else if (currpel
- es
->wleft
>= ClientWidth(wndPtr
))
1590 es
->wleft
= currpel
- (ClientWidth(wndPtr
) - 5);
1591 es
->WndCol
= currpel
- es
->wleft
;
1597 /*********************************************************************
1598 * WM_KEYDOWN message function
1601 void EDIT_KeyDownMsg(HWND hwnd
, WORD wParam
)
1603 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1605 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1607 dprintf_edit(stddeb
,"EDIT_KeyDownMsg: key=%x\n", wParam
);
1614 EDIT_ClearSel(hwnd
);
1618 EDIT_Backward(hwnd
);
1623 EDIT_ClearSel(hwnd
);
1625 EDIT_Downward(hwnd
);
1632 EDIT_ClearSel(hwnd
);
1638 EDIT_ClearSel(hwnd
);
1639 EDIT_Backward(hwnd
);
1644 EDIT_ClearSel(hwnd
);
1650 EDIT_ClearSel(hwnd
);
1658 EDIT_ClearSel(hwnd
);
1659 EDIT_KeyVScrollPage(hwnd
, SB_PAGEUP
);
1667 EDIT_ClearSel(hwnd
);
1668 EDIT_KeyVScrollPage(hwnd
, SB_PAGEDOWN
);
1674 EDIT_DeleteSel(hwnd
);
1677 if (es
->CurrCol
== 0 && es
->CurrLine
== 0)
1679 EDIT_Backward(hwnd
);
1686 EDIT_DeleteSel(hwnd
);
1692 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1697 /*********************************************************************
1700 * Scroll text horizontally using cursor keys.
1703 void EDIT_KeyHScroll(HWND hwnd
, WORD opt
)
1706 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1708 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1710 if (opt
== SB_LINEDOWN
)
1712 es
->wleft
+= HSCROLLDIM
;
1713 es
->WndCol
-= HSCROLLDIM
;
1719 if (es
->wleft
- HSCROLLDIM
< 0)
1721 es
->WndCol
+= es
->wleft
;
1726 es
->wleft
-= HSCROLLDIM
;
1727 es
->WndCol
+= HSCROLLDIM
;
1731 InvalidateRect(hwnd
, NULL
, FALSE
);
1736 hscrollpos
= EDIT_ComputeHScrollPos(hwnd
);
1737 SetScrollPos(hwnd
, SB_HORZ
, hscrollpos
, TRUE
);
1742 /*********************************************************************
1743 * EDIT_KeyVScrollLine
1745 * Scroll text vertically by one line using keyboard.
1748 void EDIT_KeyVScrollLine(HWND hwnd
, WORD opt
)
1752 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1754 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1759 if (opt
== SB_LINEDOWN
)
1761 /* move down one line */
1762 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
1768 /* move up one line */
1774 if (IsWindowVisible(hwnd
))
1776 /* adjust client bottom to nearest whole line */
1777 GetClientRect(hwnd
, &rc
);
1778 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
1780 if (opt
== SB_LINEUP
)
1782 /* move up one line (scroll window down) */
1783 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
1784 /* write top line */
1785 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
1790 /* move down one line (scroll window up) */
1791 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
1792 /* write bottom line */
1793 y
= (((rc
.bottom
- rc
.top
) / es
->txtht
) - 1);
1794 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
1799 /* reset the vertical scroll bar */
1802 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1803 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1808 /*********************************************************************
1809 * EDIT_KeyVScrollPage
1811 * Scroll text vertically by one page using keyboard.
1814 void EDIT_KeyVScrollPage(HWND hwnd
, WORD opt
)
1817 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1819 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1823 if (opt
== SB_PAGEUP
)
1826 es
->wtop
-= ClientHeight(wndPtr
, es
);
1830 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1832 es
->wtop
+= ClientHeight(wndPtr
, es
);
1833 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
1834 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1840 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
1841 EDIT_StickEnd(hwnd
);
1842 InvalidateRect(hwnd
, NULL
, TRUE
);
1845 /* reset the vertical scroll bar */
1848 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1849 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1855 /*********************************************************************
1856 * EDIT_KeyVScrollDoc
1858 * Scroll text to top and bottom of document using keyboard.
1861 void EDIT_KeyVScrollDoc(HWND hwnd
, WORD opt
)
1864 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1866 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1872 es
->wtop
= es
->wleft
= 0;
1873 else if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1875 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1879 es
->CurrLine
= es
->wlines
;
1880 es
->WndRow
= es
->wlines
- es
->wtop
;
1882 InvalidateRect(hwnd
, NULL
, TRUE
);
1885 /* reset the vertical scroll bar */
1888 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1889 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1894 /*********************************************************************
1895 * EDIT_ComputeVScrollPos
1897 * Compute the vertical scroll bar position from the window
1898 * position and text width.
1901 int EDIT_ComputeVScrollPos(HWND hwnd
)
1904 short minpos
, maxpos
;
1905 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1907 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1909 GetScrollRange(hwnd
, SB_VERT
, &minpos
, &maxpos
);
1911 if (es
->wlines
> ClientHeight(wndPtr
, es
))
1912 vscrollpos
= (double)(es
->wtop
) / (double)(es
->wlines
-
1913 ClientHeight(wndPtr
, es
)) * (maxpos
- minpos
);
1915 vscrollpos
= minpos
;
1921 /*********************************************************************
1922 * EDIT_ComputeHScrollPos
1924 * Compute the horizontal scroll bar position from the window
1925 * position and text width.
1928 int EDIT_ComputeHScrollPos(HWND hwnd
)
1931 short minpos
, maxpos
;
1932 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1934 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1936 GetScrollRange(hwnd
, SB_HORZ
, &minpos
, &maxpos
);
1938 if (es
->textwidth
> ClientWidth(wndPtr
))
1939 hscrollpos
= (double)(es
->wleft
) / (double)(es
->textwidth
-
1940 ClientWidth(wndPtr
)) * (maxpos
- minpos
);
1942 hscrollpos
= minpos
;
1948 /*********************************************************************
1951 * Delete character to right of cursor.
1954 void EDIT_DelKey(HWND hwnd
)
1957 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1959 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1960 char *currchar
= CurrChar
;
1961 BOOL repaint
= *currchar
== '\n';
1963 if (IsMultiLine() && *currchar
== '\n' && *(currchar
+ 1) == '\0')
1965 strcpy(currchar
, currchar
+ 1);
1966 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1970 EDIT_BuildTextPointers(hwnd
);
1971 GetClientRect(hwnd
, &rc
);
1972 rc
.top
= es
->WndRow
* es
->txtht
;
1973 InvalidateRect(hwnd
, &rc
, FALSE
);
1978 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, -1);
1979 EDIT_WriteTextLine(hwnd
, NULL
, es
->WndRow
+ es
->wtop
);
1982 es
->TextChanged
= TRUE
;
1983 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1986 /*********************************************************************
1987 * WM_VSCROLL message function
1990 void EDIT_VScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
1992 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1994 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2004 EDIT_VScrollLine(hwnd
, wParam
);
2009 EDIT_VScrollPage(hwnd
, wParam
);
2014 SetCaretPos(es
->WndCol
, es
->WndRow
);
2019 /*********************************************************************
2022 * Scroll text vertically by one line using scrollbars.
2025 void EDIT_VScrollLine(HWND hwnd
, WORD opt
)
2029 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2031 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2033 dprintf_edit(stddeb
,"EDIT_VScrollLine: direction=%d\n", opt
);
2035 if (opt
== SB_LINEDOWN
)
2037 /* move down one line */
2038 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
2044 /* move up one line */
2050 if (IsWindowVisible(hwnd
))
2052 /* adjust client bottom to nearest whole line */
2053 GetClientRect(hwnd
, &rc
);
2054 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
2056 if (opt
== SB_LINEUP
)
2058 /* move up one line (scroll window down) */
2059 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
2060 /* write top line */
2061 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
2066 /* move down one line (scroll window up) */
2067 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
2068 /* write bottom line */
2069 y
= ((rc
.bottom
- rc
.top
/ es
->txtht
) - 1);
2070 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
2077 /*********************************************************************
2080 * Scroll text vertically by one page using keyboard.
2083 void EDIT_VScrollPage(HWND hwnd
, WORD opt
)
2086 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2088 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2090 if (opt
== SB_PAGEUP
)
2093 es
->wtop
-= ClientHeight(wndPtr
, es
);
2097 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
2099 es
->wtop
+= ClientHeight(wndPtr
, es
);
2100 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
2101 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
2107 InvalidateRect(hwnd
, NULL
, TRUE
);
2110 /* reset the vertical scroll bar */
2113 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
2114 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
2119 /*********************************************************************
2120 * WM_HSCROLL message function
2123 void EDIT_HScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2125 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2127 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2135 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
2142 /*********************************************************************
2143 * WM_SIZE message function
2146 void EDIT_SizeMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2148 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2150 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2152 if (wParam
!= SIZE_MAXIMIZED
&& wParam
!= SIZE_RESTORED
) return;
2154 InvalidateRect(hwnd
, NULL
, TRUE
);
2155 es
->PaintBkgd
= TRUE
;
2160 /*********************************************************************
2161 * WM_LBUTTONDOWN message function
2164 void EDIT_LButtonDownMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2169 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2171 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2174 EDIT_ClearSel(hwnd
);
2176 es
->WndRow
= HIWORD(lParam
) / es
->txtht
;
2179 else if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2181 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2184 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2186 cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
2187 len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
2188 es
->WndCol
= LOWORD(lParam
) + es
->wleft
;
2189 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0) || end
)
2190 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0);
2191 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2192 es
->WndCol
-= es
->wleft
;
2195 ButtonRow
= es
->CurrLine
;
2196 ButtonCol
= es
->CurrCol
;
2200 /*********************************************************************
2201 * WM_MOUSEMOVE message function
2204 void EDIT_MouseMoveMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2206 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2208 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2210 if (wParam
!= MK_LBUTTON
)
2216 EDIT_SetAnchor(hwnd
, ButtonRow
, ButtonCol
);
2223 EDIT_ExtendSel(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
2224 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
2230 /*********************************************************************
2233 * Convert a pixel offset in the given row to a character offset,
2234 * adjusting the pixel offset to the nearest whole character if
2238 int EDIT_PixelToChar(HWND hwnd
, int row
, int *pixel
)
2240 int ch
= 0, i
= 0, s_i
= 0;
2243 dprintf_edit(stddeb
,"EDIT_PixelToChar: row=%d, pixel=%d\n", row
, *pixel
);
2245 text
= EDIT_TextLine(hwnd
, row
);
2249 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(text
+ ch
)), i
);
2253 /* if stepped past _pixel_, go back a character */
2264 /*********************************************************************
2265 * WM_SETTEXT message function
2268 LONG
EDIT_SetTextMsg(HWND hwnd
, LONG lParam
)
2272 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2274 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2276 if (strlen((char *)PTR_SEG_TO_LIN(lParam
)) <= es
->MaxTextLen
)
2278 len
= ( lParam
? strlen((char *)PTR_SEG_TO_LIN(lParam
)) : 0 );
2279 EDIT_ClearText(hwnd
);
2281 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, len
+ 3);
2282 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2284 strcpy(text
, (char *)PTR_SEG_TO_LIN(lParam
));
2286 text
[len
+ 1] = '\0';
2287 text
[len
+ 2] = '\0';
2288 EDIT_BuildTextPointers(hwnd
);
2289 InvalidateRect(hwnd
, NULL
, TRUE
);
2290 es
->PaintBkgd
= TRUE
;
2291 es
->TextChanged
= TRUE
;
2299 /*********************************************************************
2302 * Clear text from text buffer.
2305 void EDIT_ClearText(HWND hwnd
)
2307 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2309 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2310 unsigned int blen
= EditBufLen(wndPtr
) + 2;
2313 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, blen
);
2314 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2315 memset(text
, 0, blen
);
2318 es
->CurrLine
= es
->CurrCol
= 0;
2319 es
->WndRow
= es
->WndCol
= 0;
2320 es
->wleft
= es
->wtop
= 0;
2322 es
->TextChanged
= FALSE
;
2323 EDIT_ClearTextPointers(hwnd
);
2327 /*********************************************************************
2328 * EM_SETSEL message function
2331 void EDIT_SetSelMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2334 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2336 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2338 so
= LOWORD(lParam
);
2339 eo
= HIWORD(lParam
);
2341 if (so
== -1) /* if so == -1, clear selection */
2343 EDIT_ClearSel(hwnd
);
2347 if (so
== eo
) /* if so == eo, set caret only */
2349 EDIT_GetLineCol(hwnd
, (int) so
, &(es
->CurrLine
), &(es
->CurrCol
));
2350 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2354 if (es
->WndRow
< 0 || es
->WndRow
> ClientHeight(wndPtr
, es
))
2356 es
->wtop
= es
->CurrLine
;
2359 es
->WndCol
= EDIT_StrLength(hwnd
,
2360 EDIT_TextLine(hwnd
, es
->CurrLine
),
2361 es
->CurrCol
, 0) - es
->wleft
;
2362 if (es
->WndCol
> ClientWidth(wndPtr
))
2364 es
->wleft
= es
->WndCol
;
2367 else if (es
->WndCol
< 0)
2369 es
->wleft
+= es
->WndCol
;
2374 else /* otherwise set selection */
2376 if (eo
>= 0 && so
> eo
) /* eo == -1 flag to extend to end of text */
2384 EDIT_GetLineCol(hwnd
, (int) so
, &(es
->SelBegLine
), &(es
->SelBegCol
));
2385 EDIT_GetLineCol(hwnd
, (int) eo
, &(es
->SelEndLine
), &(es
->SelEndCol
));
2386 es
->CurrLine
= es
->SelEndLine
;
2387 es
->CurrCol
= es
->SelEndCol
;
2388 es
->WndRow
= es
->SelEndLine
- es
->wtop
;
2390 if (!wParam
) /* don't suppress scrolling of text */
2394 es
->wtop
= es
->SelEndLine
;
2397 else if (es
->WndRow
> ClientHeight(wndPtr
, es
))
2399 es
->wtop
+= es
->WndRow
- ClientHeight(wndPtr
, es
);
2400 es
->WndRow
= ClientHeight(wndPtr
, es
);
2402 es
->WndCol
= EDIT_StrLength(hwnd
,
2403 EDIT_TextLine(hwnd
, es
->SelEndLine
),
2404 es
->SelEndCol
, 0) - es
->wleft
;
2405 if (es
->WndCol
> ClientWidth(wndPtr
))
2407 es
->wleft
+= es
->WndCol
- ClientWidth(wndPtr
);
2408 es
->WndCol
= ClientWidth(wndPtr
);
2410 else if (es
->WndCol
< 0)
2412 es
->wleft
+= es
->WndCol
;
2417 InvalidateRect(hwnd
, NULL
, TRUE
);
2423 /*********************************************************************
2426 * Return line and column in text buffer from character offset.
2429 void EDIT_GetLineCol(HWND hwnd
, int off
, int *line
, int *col
)
2433 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2435 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2436 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2437 unsigned int *textPtrs
=
2438 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2440 /* check for (0,0) */
2441 if (!off
|| !es
->wlines
)
2448 if (off
< 0 || off
> strlen(text
)) off
= strlen(text
);
2450 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2452 cp
= text
+ *(textPtrs
+ lineno
);
2453 if (off
== (int)(cp
- text
))
2459 if (off
< (int)(cp
- text
))
2464 *col
= off
- (int)(cp1
- text
);
2466 if (*(text
+ *col
) == '\0')
2472 /*********************************************************************
2475 * Delete the current selected text (if any)
2478 void EDIT_DeleteSel(HWND hwnd
)
2482 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2484 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2488 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
2489 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
2490 len
= (int)(bel
- bbl
);
2491 EDIT_SaveDeletedText(hwnd
, bbl
, len
, es
->SelBegLine
, es
->SelBegCol
);
2492 es
->TextChanged
= TRUE
;
2495 es
->CurrLine
= es
->SelBegLine
;
2496 es
->CurrCol
= es
->SelBegCol
;
2497 es
->WndRow
= es
->SelBegLine
- es
->wtop
;
2500 es
->wtop
= es
->SelBegLine
;
2503 es
->WndCol
= EDIT_StrLength(hwnd
, bbl
- es
->SelBegCol
,
2504 es
->SelBegCol
, 0) - es
->wleft
;
2506 EDIT_BuildTextPointers(hwnd
);
2507 es
->PaintBkgd
= TRUE
;
2508 EDIT_ClearSel(hwnd
);
2513 /*********************************************************************
2516 * Clear the current selection.
2519 void EDIT_ClearSel(HWND hwnd
)
2521 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2523 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2525 es
->SelBegLine
= es
->SelBegCol
= 0;
2526 es
->SelEndLine
= es
->SelEndCol
= 0;
2528 InvalidateRect(hwnd
, NULL
, TRUE
);
2533 /*********************************************************************
2534 * EDIT_TextLineNumber
2536 * Return the line number in the text buffer of the supplied
2537 * character pointer.
2540 int EDIT_TextLineNumber(HWND hwnd
, char *lp
)
2544 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2546 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2547 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2548 unsigned int *textPtrs
=
2549 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2551 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2553 cp
= text
+ *(textPtrs
+ lineno
);
2563 /*********************************************************************
2566 * Set down anchor for text marking.
2569 void EDIT_SetAnchor(HWND hwnd
, int row
, int col
)
2572 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2574 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2579 EDIT_ClearSel(hwnd
);
2581 es
->SelBegLine
= es
->SelEndLine
= row
;
2582 es
->SelBegCol
= es
->SelEndCol
= col
;
2585 InvalidateRect(hwnd
, NULL
, FALSE
);
2591 /*********************************************************************
2594 * Extend selection to the given screen co-ordinates.
2597 void EDIT_ExtendSel(HWND hwnd
, INT x
, INT y
)
2599 int bbl
, bel
, bbc
, bec
;
2602 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2604 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2606 dprintf_edit(stddeb
,"EDIT_ExtendSel: x=%d, y=%d\n", x
, y
);
2608 bbl
= es
->SelEndLine
;
2609 bbc
= es
->SelEndCol
;
2613 if ((line
= es
->wtop
+ y
/ es
->txtht
) >= es
->wlines
)
2614 line
= es
->wlines
- 1;
2619 cp
= EDIT_TextLine(hwnd
, line
);
2620 len
= EDIT_LineLength(hwnd
, line
);
2622 es
->WndRow
= y
/ es
->txtht
;
2625 else if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2626 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2627 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2628 es
->SelEndLine
= es
->CurrLine
;
2630 es
->WndCol
= es
->wleft
+ max(x
,0);
2631 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0))
2632 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0);
2633 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2634 es
->WndCol
-= es
->wleft
;
2635 es
->SelEndCol
= es
->CurrCol
;
2637 bel
= es
->SelEndLine
;
2638 bec
= es
->SelEndCol
;
2640 /* return if no new characters to mark */
2641 if (bbl
== bel
&& bbc
== bec
)
2644 /* put lowest marker first */
2650 if (bbl
== bel
&& bbc
> bec
)
2653 for (y
= bbl
; y
<= bel
; y
++)
2655 if (y
== bbl
&& y
== bel
)
2656 EDIT_WriteSel(hwnd
, y
, bbc
, bec
);
2658 EDIT_WriteSel(hwnd
, y
, bbc
, -1);
2660 EDIT_WriteSel(hwnd
, y
, 0, bec
);
2662 EDIT_WriteSel(hwnd
, y
, 0, -1);
2667 /*********************************************************************
2670 * Display selection by reversing pixels in selected text.
2671 * If end == -1, selection applies to end of line.
2674 void EDIT_WriteSel(HWND hwnd
, int y
, int start
, int end
)
2680 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2682 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2684 dprintf_edit(stddeb
,"EDIT_WriteSel: y=%d start=%d end=%d\n", y
, start
,end
);
2685 GetClientRect(hwnd
, &rc
);
2687 /* make sure y is within the window */
2688 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
2691 /* get pointer to text */
2692 cp
= EDIT_TextLine(hwnd
, y
);
2694 /* get length of line if end == -1 */
2696 end
= EDIT_LineLength(hwnd
, y
);
2698 /* For some reason Rectangle, when called with R2_XORPEN filling,
2699 * appears to leave a 2 pixel gap between characters and between
2700 * lines. I have kludged this by adding on two pixels to ecol and
2701 * to the line height in the call to Rectangle.
2703 scol
= EDIT_StrLength(hwnd
, cp
, start
, 0) - es
->wleft
;
2704 if (scol
> rc
.right
) return;
2705 if (scol
< rc
.left
) scol
= rc
.left
;
2706 ecol
= EDIT_StrLength(hwnd
, cp
, end
, 0) - es
->wleft
;
2707 if (ecol
< rc
.left
) return;
2708 if (ecol
> rc
.right
) ecol
= rc
.right
;
2711 rcInvert
.left
= scol
;
2712 rcInvert
.top
= y
* es
->txtht
;
2713 rcInvert
.right
= ecol
;
2714 rcInvert
.bottom
= (y
+ 1) * es
->txtht
;
2715 InvertRect(hdc
, (LPRECT
) &rcInvert
);
2716 ReleaseDC(hwnd
, hdc
);
2720 /*********************************************************************
2723 * Stop text marking (selection).
2726 void EDIT_StopMarking(HWND hwnd
)
2728 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2730 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2732 TextMarking
= FALSE
;
2733 if (es
->SelBegLine
> es
->SelEndLine
)
2735 swap(&(es
->SelBegLine
), &(es
->SelEndLine
));
2736 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2738 if (es
->SelBegLine
== es
->SelEndLine
&& es
->SelBegCol
> es
->SelEndCol
)
2739 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2743 /*********************************************************************
2744 * EM_GETLINE message function
2747 LONG
EDIT_GetLineMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2751 char *buffer
= (char *)lParam
;
2753 cp
= EDIT_TextLine(hwnd
, wParam
);
2754 cp1
= EDIT_TextLine(hwnd
, wParam
+ 1);
2755 len
= min((int)(cp1
- cp
), (WORD
)(*buffer
));
2756 strncpy(buffer
, cp
, len
);
2762 /*********************************************************************
2763 * EM_GETSEL message function
2766 LONG
EDIT_GetSelMsg(HWND hwnd
)
2769 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2771 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2772 unsigned int *textPtrs
=
2773 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2775 so
= *(textPtrs
+ es
->SelBegLine
) + es
->SelBegCol
;
2776 eo
= *(textPtrs
+ es
->SelEndLine
) + es
->SelEndCol
;
2778 return MAKELONG(so
, eo
);
2782 /*********************************************************************
2783 * EM_REPLACESEL message function
2786 void EDIT_ReplaceSel(HWND hwnd
, LONG lParam
)
2788 EDIT_DeleteSel(hwnd
);
2789 EDIT_InsertText(hwnd
, (char *)PTR_SEG_TO_LIN(lParam
),
2790 strlen((char *)PTR_SEG_TO_LIN(lParam
)));
2791 InvalidateRect(hwnd
, NULL
, TRUE
);
2796 /*********************************************************************
2799 * Insert text at current line and column.
2802 void EDIT_InsertText(HWND hwnd
, char *str
, int len
)
2805 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2807 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2808 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2810 plen
= strlen(text
) + len
;
2811 if (plen
+ 1 > es
->textlen
)
2813 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ len
);
2814 es
->textlen
= plen
+ 1;
2816 memmove(CurrChar
+ len
, CurrChar
, strlen(CurrChar
) + 1);
2817 memcpy(CurrChar
, str
, len
);
2819 EDIT_BuildTextPointers(hwnd
);
2820 es
->PaintBkgd
= TRUE
;
2821 es
->TextChanged
= TRUE
;
2823 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ len
) - text
), &(es
->CurrLine
),
2825 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2826 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2827 es
->CurrCol
, 0) - es
->wleft
;
2831 /*********************************************************************
2832 * EM_LINEFROMCHAR message function
2835 LONG
EDIT_LineFromCharMsg(HWND hwnd
, WORD wParam
)
2838 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2840 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2842 if (wParam
== (WORD
)-1)
2843 return (LONG
)(es
->SelBegLine
);
2845 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2851 /*********************************************************************
2852 * EM_LINEINDEX message function
2855 LONG
EDIT_LineIndexMsg(HWND hwnd
, WORD wParam
)
2857 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2859 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2860 unsigned int *textPtrs
=
2861 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2863 if (wParam
== (WORD
)-1)
2864 wParam
= es
->CurrLine
;
2866 return (LONG
)(*(textPtrs
+ wParam
));
2870 /*********************************************************************
2871 * EM_LINELENGTH message function
2874 LONG
EDIT_LineLengthMsg(HWND hwnd
, WORD wParam
)
2877 int sbl
, sbc
, sel
, sec
;
2878 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2880 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2881 unsigned int *textPtrs
=
2882 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2884 if (wParam
== (WORD
)-1)
2888 sbl
= es
->SelBegLine
;
2889 sbc
= es
->SelBegCol
;
2890 sel
= es
->SelEndLine
;
2891 sec
= es
->SelEndCol
;
2898 if (sbl
== sel
&& sbc
> sec
)
2903 len
= *(textPtrs
+ sbl
+ 1) - *(textPtrs
+ sbl
) - 1;
2904 return len
- sec
- sbc
;
2907 len
= *(textPtrs
+ sel
+ 1) - *(textPtrs
+ sel
) - sec
- 1;
2910 else /* no selection marked */
2912 len
= *(textPtrs
+ es
->CurrLine
+ 1) -
2913 *(textPtrs
+ es
->CurrLine
) - 1;
2917 else /* line number specified */
2919 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2920 len
= *(textPtrs
+ row
+ 1) - *(textPtrs
+ row
);
2926 /*********************************************************************
2927 * WM_SETFONT message function
2930 void EDIT_SetFont(HWND hwnd
, WORD wParam
, LONG lParam
)
2935 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2937 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2938 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
2942 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
2943 GetCharWidth(hdc
, 0, 255, charWidths
);
2944 GetTextMetrics(hdc
, &tm
);
2945 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
2946 SelectObject(hdc
, (HANDLE
)oldfont
);
2947 ReleaseDC(hwnd
, hdc
);
2949 es
->WndRow
= (es
->CurrLine
- es
->wtop
) / es
->txtht
;
2950 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2951 es
->CurrCol
, 0) - es
->wleft
;
2953 InvalidateRect(hwnd
, NULL
, TRUE
);
2954 es
->PaintBkgd
= TRUE
;
2955 if (lParam
) UpdateWindow(hwnd
);
2959 /*********************************************************************
2960 * EDIT_SaveDeletedText
2962 * Save deleted text in deleted text buffer.
2965 void EDIT_SaveDeletedText(HWND hwnd
, char *deltext
, int len
,
2969 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2971 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2973 if (!es
->hDeletedText
)
2974 es
->hDeletedText
= GlobalAlloc( GMEM_MOVEABLE
, len
);
2976 es
->hDeletedText
= GlobalReAlloc(es
->hDeletedText
, len
, GMEM_MOVEABLE
);
2977 if (!es
->hDeletedText
) return;
2978 text
= (char *)GlobalLock(es
->hDeletedText
);
2979 memcpy(text
, deltext
, len
);
2980 GlobalUnlock(es
->hDeletedText
);
2981 es
->DeletedLength
= len
;
2982 es
->DeletedCurrLine
= line
;
2983 es
->DeletedCurrCol
= col
;
2987 /*********************************************************************
2988 * EDIT_ClearDeletedText
2990 * Clear deleted text buffer.
2993 void EDIT_ClearDeletedText(HWND hwnd
)
2995 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2997 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2999 GlobalFree(es
->hDeletedText
);
3000 es
->hDeletedText
= 0;
3001 es
->DeletedLength
= 0;
3005 /*********************************************************************
3006 * EM_UNDO message function
3009 LONG
EDIT_UndoMsg(HWND hwnd
)
3012 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3014 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3016 if (es
->hDeletedText
)
3018 text
= (char *)GlobalLock(es
->hDeletedText
);
3019 es
->CurrLine
= es
->DeletedCurrLine
;
3020 es
->CurrCol
= es
->DeletedCurrCol
;
3021 EDIT_InsertText(hwnd
, text
, es
->DeletedLength
);
3022 GlobalUnlock(es
->hDeletedText
);
3023 EDIT_ClearDeletedText(hwnd
);
3025 es
->SelBegLine
= es
->CurrLine
;
3026 es
->SelBegCol
= es
->CurrCol
;
3027 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ es
->DeletedLength
) - text
),
3028 &(es
->CurrLine
), &(es
->CurrCol
));
3029 es
->WndRow
= es
->CurrLine
- es
->wtop
;
3030 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
3031 es
->CurrCol
, 0) - es
->wleft
;
3032 es
->SelEndLine
= es
->CurrLine
;
3033 es
->SelEndCol
= es
->CurrCol
;
3035 InvalidateRect(hwnd
, NULL
, TRUE
);
3044 /*********************************************************************
3047 * Allocate the specified number of bytes on the specified local heap.
3050 unsigned int EDIT_HeapAlloc(HWND hwnd
, int bytes
)
3052 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3055 ret
= LOCAL_Alloc( wndPtr
->hInstance
, LMEM_FIXED
, bytes
);
3057 printf("EDIT_HeapAlloc: Out of heap-memory\n");
3062 /*********************************************************************
3065 * Return the address of the memory pointed to by the handle.
3068 void *EDIT_HeapAddr(HWND hwnd
, unsigned int handle
)
3070 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3071 return handle
? PTR_SEG_OFF_TO_LIN( wndPtr
->hInstance
, handle
) : 0;
3075 /*********************************************************************
3078 * Reallocate the memory pointed to by the handle.
3081 unsigned int EDIT_HeapReAlloc(HWND hwnd
, unsigned int handle
, int bytes
)
3083 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3085 return LOCAL_ReAlloc( wndPtr
->hInstance
, handle
, bytes
, LMEM_FIXED
);
3089 /*********************************************************************
3092 * Frees the memory pointed to by the handle.
3095 void EDIT_HeapFree(HWND hwnd
, unsigned int handle
)
3097 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3099 LOCAL_Free( wndPtr
->hInstance
, handle
);
3103 /*********************************************************************
3106 * Return the size of the given object on the local heap.
3109 unsigned int EDIT_HeapSize(HWND hwnd
, unsigned int handle
)
3111 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3114 return HEAP_LocalSize((MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2), handle
);
3116 return LOCAL_Size( wndPtr
->hInstance
, handle
);
3120 /*********************************************************************
3121 * EM_SETHANDLE message function
3124 void EDIT_SetHandleMsg(HWND hwnd
, WORD wParam
)
3126 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3128 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3133 es
->textlen
= EDIT_HeapSize(hwnd
, es
->hText
);
3135 es
->wtop
= es
->wleft
= 0;
3136 es
->CurrLine
= es
->CurrCol
= 0;
3137 es
->WndRow
= es
->WndCol
= 0;
3138 es
->TextChanged
= FALSE
;
3140 es
->SelBegLine
= es
->SelBegCol
= 0;
3141 es
->SelEndLine
= es
->SelEndCol
= 0;
3142 dprintf_edit(stddeb
, "EDIT_SetHandleMsg: textlen=%d\n",
3145 EDIT_BuildTextPointers(hwnd
);
3146 es
->PaintBkgd
= TRUE
;
3147 InvalidateRect(hwnd
, NULL
, TRUE
);
3153 /*********************************************************************
3154 * EM_SETTABSTOPS message function
3157 LONG
EDIT_SetTabStopsMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
3159 unsigned short *tabstops
;
3160 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3162 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3164 es
->NumTabStops
= wParam
;
3166 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3167 else if (wParam
== 1)
3169 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3170 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3171 *tabstops
= (unsigned short)lParam
;
3175 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, wParam
);
3176 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3177 memcpy(tabstops
, (unsigned short *)lParam
, wParam
);
3183 /*********************************************************************
3184 * EDIT_CopyToClipboard
3186 * Copy the specified text to the clipboard.
3189 void EDIT_CopyToClipboard(HWND hwnd
)
3195 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3197 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3199 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
3200 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
3201 len
= (int)(bel
- bbl
);
3203 hMem
= GlobalAlloc(GHND
, (DWORD
)(len
+ 1));
3204 lpMem
= GlobalLock(hMem
);
3206 for (i
= 0; i
< len
; i
++)
3210 OpenClipboard(hwnd
);
3212 SetClipboardData(CF_TEXT
, hMem
);
3217 /*********************************************************************
3218 * WM_PASTE message function
3221 void EDIT_PasteMsg(HWND hwnd
)
3226 OpenClipboard(hwnd
);
3227 if (!(hClipMem
= GetClipboardData(CF_TEXT
)))
3229 /* no text in clipboard */
3233 lpClipMem
= GlobalLock(hClipMem
);
3234 EDIT_InsertText(hwnd
, lpClipMem
, strlen(lpClipMem
));
3235 GlobalUnlock(hClipMem
);
3237 InvalidateRect(hwnd
, NULL
, TRUE
);
3242 /*********************************************************************
3246 void swap(int *a
, int *b
)