Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

editml.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define LINEBUMP   32
#define ML_REFRESH   0xffffffff

Functions

__inline void MLSanityCheck (PED ped)
UINT MLGetLineWidth (HDC hdc, LPSTR lpstr, int nCnt, PED ped)
void MLSize (PED ped, BOOL fRedraw)
int MLCalcXOffset (PED ped, HDC hdc, int lineNumber)
ICH MLMoveSelection (PED ped, ICH ich, BOOL fLeft)
ICH MLMoveSelectionRestricted (PED ped, ICH ich, BOOL fLeft)
void MLSetCaretPosition (PED ped, HDC hdc)
ICH MLLine (PED ped, ICH lineNumber)
int MLIchToLine (PED ped, ICH ich)
INT MLIchToYPos (PED ped, ICH ich, BOOL prevLine)
void MLIchToXYPos (PED ped, HDC hdc, ICH ich, BOOL prevLine, LPPOINT ppt)
ICH MLMouseToIch (PED ped, HDC hdc, LPPOINT mousePt, LPICH pline)
void MLChangeSelection (PED ped, HDC hdc, ICH ichNewMinSel, ICH ichNewMaxSel)
void MLUpdateiCaretLine (PED ped)
ICH MLInsertText (PED ped, LPSTR lpText, ICH cchInsert, BOOL fUserTyping)
void MLReplaceSel (PED ped, LPSTR lpText)
ICH MLDeleteText (PED ped)
BOOL MLInsertchLine (PED ped, ICH iLine, ICH ich, BOOL fUserTyping)
void MLShiftchLines (PED ped, ICH iLine, int delta)
void MLBuildchLines (PED ped, ICH iLine, int cchDelta, BOOL fUserTyping, PLONG pll, PLONG phl)
void MLPaint (PED ped, HDC hdc, LPRECT lprc)
void MLKeyDown (PED ped, UINT virtKeyCode, int keyMods)
void MLChar (PED ped, DWORD keyValue, int keyMods)
ICH PASCAL NEAR MLPasteText (PED ped)
void MLMouseMotion (PED ped, UINT message, UINT virtKeyDown, LPPOINT mousePt)
LONG MLScroll (PED ped, BOOL fVertical, int cmd, int iAmt, BOOL fRedraw)
void MLSetFocus (PED ped)
void MLKillFocus (PED ped)
BOOL MLEnsureCaretVisible (PED ped)
LRESULT MLEditWndProc (HWND hwnd, PED ped, UINT message, WPARAM wParam, LPARAM lParam)
void MLDrawText (PED ped, HDC hdc, ICH ichStart, ICH ichEnd, BOOL fSelChange)


Define Documentation

#define LINEBUMP   32
 

Definition at line 17 of file editml.c.

Referenced by MLInsertchLine().

#define ML_REFRESH   0xffffffff
 

Definition at line 22 of file editml.c.

Referenced by MLBuildchLines(), MLScroll(), and MLSize().


Function Documentation

void MLBuildchLines PED  ped,
ICH  iLine,
int  cchDelta,
BOOL  fUserTyping,
PLONG  pll,
PLONG  phl
 

Definition at line 1562 of file editml.c.

References AWCOMPARECHAR, BOOL, CALLWORDBREAKPROC, tagED::cbChar, tagED::cch, tagED::chLines, tagED::cLines, DWORD, ECAdjustIch(), ECAnsiPrev(), ECCchInWidth(), ECGetEditDC(), ECIsDBCSLeadByte(), ECLock(), ECNextIch(), ECReleaseEditDC(), ECUnlock(), ECWord(), tagLPKEDITCALLOUT::EditCchInWidth, tagLPKEDITCALLOUT::EditGetLineWidth, FALSE, tagED::fAnsi, tagED::fCalcLines, tagED::fDBCS, tagED::fWrap, ICH, tagED::ichScreenStart, ISDELIMETERA, ISDELIMETERW, tagED::lpfnNextWord, max, MAXLINELENGTH, tagED::maxPixelWidth, ML_REFRESH, MLGetLineWidth(), MLInsertchLine(), MLSanityCheck(), MLScroll(), MLShiftchLines(), NULL, tagED::pLpkEditCallout, tagED::rcFmt, TRUE, UINT, UserIsFullWidth(), and tagED::xOffset.

Referenced by ECResetTextInfo(), ECSetFont(), ECUpdateFormat(), MLDeleteText(), MLEditWndProc(), MLInsertText(), MLSetTabStops(), and MLSize().

01569 { 01570 PSTR ptext; /* Starting address of the text */ 01571 01572 /* 01573 * We keep these ICH's so that we can Unlock ped->hText when we have to grow 01574 * the chlines array. With large text handles, it becomes a problem if we 01575 * have a locked block in the way. 01576 */ 01577 ICH ichLineStart; 01578 ICH ichLineEnd; 01579 ICH ichLineEndBeforeCRLF; 01580 ICH ichCRLF; 01581 01582 ICH cch; 01583 HDC hdc; 01584 01585 BOOL fLineBroken = FALSE; /* Initially, no new line breaks are made */ 01586 ICH minCchBreak; 01587 ICH maxCchBreak; 01588 BOOL fOnDelimiter; 01589 01590 if (!ped->cch) { 01591 ped->maxPixelWidth = 0; 01592 ped->xOffset = 0; 01593 ped->ichScreenStart = 0; 01594 ped->cLines = 1; 01595 01596 if (pll) 01597 *pll = 0; 01598 if (phl) 01599 *phl = 0; 01600 01601 goto UpdateScroll; 01602 } 01603 01604 if (fUserTyping && cchDelta) 01605 MLShiftchLines(ped, iLine + 1, cchDelta); 01606 01607 hdc = ECGetEditDC(ped, TRUE); 01608 01609 if (!iLine && !cchDelta && !fUserTyping) { 01610 01611 /* 01612 * Reset maxpixelwidth only if we will be running through the whole 01613 * text. Better too long than too short. 01614 */ 01615 ped->maxPixelWidth = 0; 01616 01617 /* 01618 * Reset number of lines in text since we will be running through all 01619 * the text anyway... 01620 */ 01621 ped->cLines = 1; 01622 } 01623 01624 /* 01625 * Set min and max line built to be the starting line 01626 */ 01627 minCchBreak = maxCchBreak = (cchDelta ? ped->chLines[iLine] : 0); 01628 01629 ptext = ECLock(ped); 01630 01631 ichCRLF = ichLineStart = ped->chLines[iLine]; 01632 01633 while (ichLineStart < ped->cch) { 01634 if (ichLineStart >= ichCRLF) { 01635 ichCRLF = ichLineStart; 01636 01637 /* 01638 * Move ichCRLF ahead to either the first CR or to the end of text. 01639 */ 01640 if (ped->fAnsi) { 01641 while (ichCRLF < ped->cch) { 01642 if (*(ptext + ichCRLF) == 0x0D) { 01643 if (*(ptext + ichCRLF + 1) == 0x0A || 01644 *(WORD UNALIGNED *)(ptext + ichCRLF + 1) == 0x0A0D) 01645 break; 01646 } 01647 ichCRLF++; 01648 } 01649 } else { 01650 LPWSTR pwtext = (LPWSTR)ptext; 01651 01652 while (ichCRLF < ped->cch) { 01653 if (*(pwtext + ichCRLF) == 0x0D) { 01654 if (*(pwtext + ichCRLF + 1) == 0x0A || 01655 *(DWORD UNALIGNED *)(pwtext + ichCRLF + 1) == 0x000A000D) 01656 break; 01657 } 01658 ichCRLF++; 01659 } 01660 } 01661 } 01662 01663 01664 if (!ped->fWrap) { 01665 01666 UINT LineWidth; 01667 /* 01668 * If we are not word wrapping, line breaks are signified by CRLF. 01669 */ 01670 01671 // 01672 // If we cut off the line at MAXLINELENGTH, we should 01673 // adjust ichLineEnd. 01674 // 01675 if ((ichCRLF - ichLineStart) <= MAXLINELENGTH) { 01676 ichLineEnd = ichCRLF; 01677 } else { 01678 ichLineEnd = ichLineStart + MAXLINELENGTH; 01679 if (ped->fAnsi && ped->fDBCS) { 01680 ichLineEnd = ECAdjustIch( ped, (PSTR)ptext, ichLineEnd); 01681 } 01682 } 01683 01684 /* 01685 * We will keep track of what the longest line is for the horizontal 01686 * scroll bar thumb positioning. 01687 */ 01688 if (ped->pLpkEditCallout) { 01689 LineWidth = ped->pLpkEditCallout->EditGetLineWidth( 01690 ped, hdc, ptext + ichLineStart*ped->cbChar, 01691 ichLineEnd - ichLineStart); 01692 } else { 01693 LineWidth = MLGetLineWidth(hdc, ptext + ichLineStart * ped->cbChar, 01694 ichLineEnd - ichLineStart, 01695 ped); 01696 } 01697 ped->maxPixelWidth = max(ped->maxPixelWidth,(int)LineWidth); 01698 01699 } else { 01700 01701 /* 01702 * Check if the width of the edit control is non-zero; 01703 * a part of the fix for Bug #7402 -- SANKAR -- 01/21/91 -- 01704 */ 01705 if(ped->rcFmt.right > ped->rcFmt.left) { 01706 01707 /* 01708 * Find the end of the line based solely on text extents 01709 */ 01710 if (ped->pLpkEditCallout) { 01711 ichLineEnd = ichLineStart + 01712 ped->pLpkEditCallout->EditCchInWidth( 01713 ped, hdc, ptext + ped->cbChar*ichLineStart, 01714 ichCRLF - ichLineStart, 01715 ped->rcFmt.right - ped->rcFmt.left); 01716 } else { 01717 if (ped->fAnsi) { 01718 ichLineEnd = ichLineStart + 01719 ECCchInWidth(ped, hdc, 01720 ptext + ichLineStart, 01721 ichCRLF - ichLineStart, 01722 ped->rcFmt.right - ped->rcFmt.left, 01723 TRUE); 01724 } else { 01725 ichLineEnd = ichLineStart + 01726 ECCchInWidth(ped, hdc, 01727 (LPSTR)((LPWSTR)ptext + ichLineStart), 01728 ichCRLF - ichLineStart, 01729 ped->rcFmt.right - ped->rcFmt.left, 01730 TRUE); 01731 } 01732 } 01733 } else { 01734 ichLineEnd = ichLineStart; 01735 } 01736 01737 if (ichLineEnd == ichLineStart && ichCRLF - ichLineStart) { 01738 01739 /* 01740 * Maintain a minimum of one char per line 01741 */ 01742 // 01743 // Since it might be a double byte char, so calling ECNextIch. 01744 // 01745 ichLineEnd = ECNextIch(ped, NULL, ichLineEnd); 01746 } 01747 01748 /* 01749 * Now starting from ichLineEnd, if we are not at a hard line break, 01750 * then if we are not at a space AND the char before us is 01751 * not a space,(OR if we are at a CR) we will look word left for the 01752 * start of the word to break at. 01753 * This change was done for TWO reasons: 01754 * 1. If we are on a delimiter, no need to look word left to break at. 01755 * 2. If the previous char is a delimter, we can break at current char. 01756 * Change done by -- SANKAR --01/31/91-- 01757 */ 01758 if (ichLineEnd != ichCRLF) { 01759 if(ped->lpfnNextWord) { 01760 fOnDelimiter = (CALLWORDBREAKPROC(*ped->lpfnNextWord, ptext, 01761 ichLineEnd, ped->cch, WB_ISDELIMITER) || 01762 CALLWORDBREAKPROC(*ped->lpfnNextWord, ptext, ichLineEnd - 1, 01763 ped->cch, WB_ISDELIMITER)); 01764 // 01765 // This change was done for FOUR reasons: 01766 // 01767 // 1. If we are on a delimiter, no need to look word left to break at. 01768 // 2. If we are on a double byte character, we can break at current char. 01769 // 3. If the previous char is a delimter, we can break at current char. 01770 // 4. If the previous char is a double byte character, we can break at current char. 01771 // 01772 } else if (ped->fAnsi) { 01773 fOnDelimiter = (ISDELIMETERA(*(ptext + ichLineEnd)) || 01774 ECIsDBCSLeadByte(ped, *(ptext + ichLineEnd))); 01775 if (!fOnDelimiter) { 01776 PSTR pPrev = ECAnsiPrev(ped,ptext,ptext+ichLineEnd); 01777 01778 fOnDelimiter = ISDELIMETERA(*pPrev) || 01779 ECIsDBCSLeadByte(ped,*pPrev); 01780 } 01781 } else { // Unicode 01782 fOnDelimiter = (ISDELIMETERW(*((LPWSTR)ptext + ichLineEnd)) || 01783 UserIsFullWidth(CP_ACP,*((LPWSTR)ptext + ichLineEnd)) || 01784 ISDELIMETERW(*((LPWSTR)ptext + ichLineEnd - 1)) || 01785 UserIsFullWidth(CP_ACP,*((LPWSTR)ptext + ichLineEnd - 1))); 01786 } 01787 if (!fOnDelimiter || 01788 (ped->fAnsi && *(ptext + ichLineEnd) == 0x0D) || 01789 (!ped->fAnsi && *((LPWSTR)ptext + ichLineEnd) == 0x0D)) { 01790 01791 if (ped->lpfnNextWord != NULL) { 01792 cch = CALLWORDBREAKPROC(*ped->lpfnNextWord, (LPSTR)ptext, ichLineEnd, 01793 ped->cch, WB_LEFT); 01794 } else { 01795 ped->fCalcLines = TRUE; 01796 ECWord(ped, ichLineEnd, TRUE, &cch, NULL); 01797 ped->fCalcLines = FALSE; 01798 } 01799 if (cch > ichLineStart) { 01800 ichLineEnd = cch; 01801 } 01802 01803 /* 01804 * Now, if the above test fails, it means the word left goes 01805 * back before the start of the line ie. a word is longer 01806 * than a line on the screen. So, we just fit as much of 01807 * the word on the line as possible. Thus, we use the 01808 * pLineEnd we calculated solely on width at the beginning 01809 * of this else block... 01810 */ 01811 } 01812 } 01813 } 01814 #if 0 01815 if (!ISDELIMETERAW((*(ptext + (ichLineEnd - 1)*ped->cbChar))) && ISDELIMETERAW((*(ptext + ichLineEnd*ped->cbChar)))) #ERROR 01816 01817 if ((*(ptext + ichLineEnd - 1) != ' ' && 01818 *(ptext + ichLineEnd - 1) != VK_TAB) && 01819 (*(ptext + ichLineEnd) == ' ' || 01820 *(ptext + ichLineEnd) == VK_TAB)) 01821 #endif 01822 if (AWCOMPARECHAR(ped,ptext + ichLineEnd * ped->cbChar, ' ') || 01823 AWCOMPARECHAR(ped,ptext + ichLineEnd * ped->cbChar, VK_TAB)) { 01824 /* 01825 * Swallow the space at the end of a line. 01826 */ 01827 if (ichLineEnd < ped->cch) { 01828 ichLineEnd++; 01829 } 01830 } 01831 01832 /* 01833 * Skip over crlf or crcrlf if it exists. Thus, ichLineEnd is the first 01834 * character in the next line. 01835 */ 01836 ichLineEndBeforeCRLF = ichLineEnd; 01837 01838 if (ped->fAnsi) { 01839 if (ichLineEnd < ped->cch && *(ptext + ichLineEnd) == 0x0D) 01840 ichLineEnd += 2; 01841 01842 /* 01843 * Skip over CRCRLF 01844 */ 01845 if (ichLineEnd < ped->cch && *(ptext + ichLineEnd) == 0x0A) 01846 ichLineEnd++; 01847 UserAssert(ichLineEnd <= ped->cch); 01848 } else { 01849 if (ichLineEnd < ped->cch && *(((LPWSTR)ptext) + ichLineEnd) == 0x0D) 01850 ichLineEnd += 2; 01851 01852 /* 01853 * Skip over CRCRLF 01854 */ 01855 if (ichLineEnd < ped->cch && *(((LPWSTR)ptext) + ichLineEnd) == 0x0A) { 01856 ichLineEnd++; 01857 RIPMSG0(RIP_VERBOSE, "Skip over CRCRLF\n"); 01858 } 01859 UserAssert(ichLineEnd <= ped->cch); 01860 } 01861 01862 /* 01863 * Now, increment iLine, allocate space for the next line, and set its 01864 * starting point 01865 */ 01866 iLine++; 01867 01868 if (!fUserTyping || (iLine > ped->cLines - 1) || (ped->chLines[iLine] != ichLineEnd)) { 01869 01870 /* 01871 * The line break occured in a different place than before. 01872 */ 01873 if (!fLineBroken) { 01874 01875 /* 01876 * Since we haven't broken a line before, just set the min 01877 * break line. 01878 */ 01879 fLineBroken = TRUE; 01880 if (ichLineEndBeforeCRLF == ichLineEnd) 01881 minCchBreak = maxCchBreak = (ichLineEnd ? ichLineEnd - 1 : 0); 01882 else 01883 minCchBreak = maxCchBreak = ichLineEndBeforeCRLF; 01884 } 01885 maxCchBreak = max(maxCchBreak, ichLineEnd); 01886 01887 ECUnlock(ped); 01888 01889 /* 01890 * Now insert the new line into the array 01891 */ 01892 if (!MLInsertchLine(ped, iLine, ichLineEnd, (BOOL)(cchDelta != 0))) 01893 goto EndUp; 01894 01895 ptext = ECLock(ped); 01896 } else { 01897 maxCchBreak = ped->chLines[iLine]; 01898 01899 /* 01900 * Quick escape 01901 */ 01902 goto UnlockAndEndUp; 01903 } 01904 01905 ichLineStart = ichLineEnd; 01906 } /* end while (ichLineStart < ped->cch) */ 01907 01908 01909 if (iLine != ped->cLines) { 01910 RIPMSG1(RIP_VERBOSE, "chLines[%d] is being cleared.\n", iLine); 01911 ped->cLines = iLine; 01912 ped->chLines[ped->cLines] = 0; 01913 } 01914 01915 /* 01916 * Note that we incremented iLine towards the end of the while loop so, the 01917 * index, iLine, is actually equal to the line count 01918 */ 01919 if (ped->cch && AWCOMPARECHAR(ped, ptext + (ped->cch - 1)*ped->cbChar, 0x0A) && 01920 ped->chLines[ped->cLines - 1] < ped->cch) { 01921 01922 /* 01923 * Make sure last line has no crlf in it 01924 */ 01925 if (!fLineBroken) { 01926 01927 /* 01928 * Since we haven't broken a line before, just set the min break 01929 * line. 01930 */ 01931 fLineBroken = TRUE; 01932 minCchBreak = ped->cch - 1; 01933 } 01934 maxCchBreak = max(maxCchBreak, ichLineEnd); 01935 ECUnlock(ped); 01936 MLInsertchLine(ped, iLine, ped->cch, FALSE); 01937 MLSanityCheck(ped); 01938 } else 01939 UnlockAndEndUp: 01940 ECUnlock(ped); 01941 01942 EndUp: 01943 ECReleaseEditDC(ped, hdc, TRUE); 01944 if (pll) 01945 *pll = minCchBreak; 01946 if (phl) 01947 *phl = maxCchBreak; 01948 01949 UpdateScroll: 01950 MLScroll(ped, FALSE, ML_REFRESH, 0, TRUE); 01951 MLScroll(ped, TRUE, ML_REFRESH, 0, TRUE); 01952 01953 MLSanityCheck(ped); 01954 01955 return; 01956 }

int MLCalcXOffset PED  ped,
HDC  hdc,
int  lineNumber
 

Definition at line 85 of file editml.c.

References tagED::cbChar, tagED::chLines, ECGetEditDC(), ECLock(), ECReleaseEditDC(), ECUnlock(), tagED::format, ICH, max, MLGetLineWidth(), MLLine(), tagED::rcFmt, and TRUE.

Referenced by MLDrawText(), MLIchToXYPos(), and MLMouseToIch().

00089 { 00090 PSTR pText; 00091 ICH lineLength; 00092 ICH lineWidth; 00093 00094 if (ped->format == ES_LEFT) 00095 return (0); 00096 00097 lineLength = MLLine(ped, lineNumber); 00098 00099 if (lineLength) { 00100 00101 pText = ECLock(ped) + ped->chLines[lineNumber] * ped->cbChar; 00102 hdc = ECGetEditDC(ped, TRUE); 00103 lineWidth = MLGetLineWidth(hdc, pText, lineLength, ped); 00104 ECReleaseEditDC(ped, hdc, TRUE); 00105 ECUnlock(ped); 00106 } else { 00107 lineWidth = 0; 00108 } 00109 00110 /* 00111 * If a SPACE or a TAB was eaten at the end of a line by MLBuildchLines 00112 * to prevent a delimiter appearing at the begining of a line, the 00113 * the following calculation will become negative causing this bug. 00114 * So, now, we take zero in such cases. 00115 * Fix for Bug #3566 --01/31/91-- SANKAR -- 00116 */ 00117 lineWidth = max(0, (int)(ped->rcFmt.right-ped->rcFmt.left-lineWidth)); 00118 00119 if (ped->format == ES_CENTER) 00120 return (lineWidth / 2); 00121 00122 if (ped->format == ES_RIGHT) { 00123 00124 /* 00125 * Subtract 1 so that the 1 pixel wide cursor will be in the visible 00126 * region on the very right side of the screen. 00127 */ 00128 return max(0, (int)(lineWidth-1)); 00129 } 00130 00131 return 0; 00132 }

void MLChangeSelection PED  ped,
HDC  hdc,
ICH  ichNewMinSel,
ICH  ichNewMaxSel
 

Definition at line 919 of file editml.c.

References _IsWindowVisible(), tagED::cch, ECCalcChangeSelection(), tagBLOCK::EndPos, tagED::fFocus, tagED::fNoHideSel, tagED::hwnd, ICH, tagED::ichMaxSel, tagED::ichMinSel, min, MLDrawText(), MLSetCaretPosition(), NtUserHideCaret(), NtUserShowCaret(), tagED::pwnd, tagBLOCK::StPos, and TRUE.

Referenced by MLKeyDown(), MLMouseMotion(), and MLSetSelection().

00924 { 00925 00926 ICH temp; 00927 ICH ichOldMinSel, ichOldMaxSel; 00928 00929 if (ichNewMinSel > ichNewMaxSel) { 00930 temp = ichNewMinSel; 00931 ichNewMinSel = ichNewMaxSel; 00932 ichNewMaxSel = temp; 00933 } 00934 ichNewMinSel = min(ichNewMinSel, ped->cch); 00935 ichNewMaxSel = min(ichNewMaxSel, ped->cch); 00936 00937 /* 00938 * Save the current selection 00939 */ 00940 ichOldMinSel = ped->ichMinSel; 00941 ichOldMaxSel = ped->ichMaxSel; 00942 00943 /* 00944 * Set new selection 00945 */ 00946 ped->ichMinSel = ichNewMinSel; 00947 ped->ichMaxSel = ichNewMaxSel; 00948 00949 /* 00950 * This finds the XOR of the old and new selection regions and redraws it. 00951 * There is nothing to repaint if we aren't visible or our selection 00952 * is hidden. 00953 */ 00954 if (_IsWindowVisible(ped->pwnd) && (ped->fFocus || ped->fNoHideSel)) { 00955 00956 BLOCK Blk[2]; 00957 int i; 00958 00959 if (ped->fFocus) { 00960 NtUserHideCaret(ped->hwnd); 00961 } 00962 00963 Blk[0].StPos = ichOldMinSel; 00964 Blk[0].EndPos = ichOldMaxSel; 00965 Blk[1].StPos = ped->ichMinSel; 00966 Blk[1].EndPos = ped->ichMaxSel; 00967 00968 if (ECCalcChangeSelection(ped, ichOldMinSel, ichOldMaxSel, (LPBLOCK)&Blk[0], (LPBLOCK)&Blk[1])) { 00969 00970 /* 00971 * Paint both Blk[0] and Blk[1], if they exist 00972 */ 00973 for (i = 0; i < 2; i++) { 00974 if (Blk[i].StPos != 0xFFFFFFFF) 00975 MLDrawText(ped, hdc, Blk[i].StPos, Blk[i].EndPos, TRUE); 00976 } 00977 } 00978 00979 /* 00980 * Update caret. 00981 */ 00982 MLSetCaretPosition(ped, hdc); 00983 00984 if (ped->fFocus) { 00985 NtUserShowCaret(ped->hwnd); 00986 } 00987 00988 } 00989 }

void MLChar PED  ped,
DWORD  keyValue,
int  keyMods
 

Definition at line 2531 of file editml.c.

References BOOL, BYTE, CTRLDOWN, DbcsCombine(), ECGetModKeys(), ECInOutReconversionMode(), ECIsCharNumeric(), ECIsDBCSLeadByte(), EFNUMBER, EFWANTRETURN, tagED::f40Compat, FALSE, tagED::fAnsi, tagED::fInDialogBox, tagED::fMouseDown, tagED::fReadOnly, HIBYTE, tagED::hwnd, tagED::ichCaret, tagED::ichMaxSel, tagED::ichMinSel, L, LOBYTE, MLDeleteText(), MLInsertText(), MLMoveSelection(), msg, NtUserCallNoParam(), NtUserMessageBeep, tagED::pwnd, SendMessage(), TestWF, TRUE, and UINT.

Referenced by MLEditWndProc(), and MLKeyDown().

02535 { 02536 WCHAR keyPress; 02537 BOOL updateText = FALSE; 02538 02539 /* 02540 * keyValue is either: 02541 * a Virtual Key (eg: VK_TAB, VK_ESCAPE, VK_BACK) 02542 * a character (Unicode or "ANSI") 02543 */ 02544 if (ped->fAnsi) 02545 keyPress = LOBYTE(keyValue); 02546 else 02547 keyPress = LOWORD(keyValue); 02548 02549 if (ped->fMouseDown || keyPress == VK_ESCAPE) { 02550 02551 /* 02552 * If we are in the middle of a mousedown command, don't do anything. 02553 * Also, just ignore it if we get a translated escape key which happens 02554 * with multiline edit controls in a dialog box. 02555 */ 02556 return ; 02557 } 02558 02559 ECInOutReconversionMode(ped, FALSE); 02560 02561 { 02562 int scState; 02563 scState = ECGetModKeys(keyMods); 02564 02565 if (ped->fInDialogBox && scState != CTRLDOWN) { 02566 02567 /* 02568 * If this multiline edit control is in a dialog box, then we want the 02569 * TAB key to take you to the next control, shift TAB to take you to the 02570 * previous control, and CTRL-TAB to insert a tab into the edit control. 02571 * We moved the focus when we received the keydown message so we will 02572 * ignore the TAB key now unless the ctrl key is down. Also, we want 02573 * CTRL-RETURN to insert a return into the text and RETURN to be sent to 02574 * the default button. 02575 */ 02576 if (keyPress == VK_TAB || 02577 (keyPress == VK_RETURN && !TestWF(ped->pwnd, EFWANTRETURN))) 02578 return ; 02579 } 02580 02581 /* 02582 * Allow CTRL+C to copy from a read only edit control 02583 * Ignore all other keys in read only controls 02584 */ 02585 if ((ped->fReadOnly) && !((keyPress == 3) && (scState == CTRLDOWN))) { 02586 return ; 02587 } 02588 } 02589 02590 switch (keyPress) { 02591 case 0x0A: // linefeed 02592 keyPress = VK_RETURN; 02593 /* 02594 * FALL THRU 02595 */ 02596 02597 case VK_RETURN: 02598 case VK_TAB: 02599 case VK_BACK: 02600 DeleteSelection: 02601 if (MLDeleteText(ped)) 02602 updateText = TRUE; 02603 break; 02604 02605 default: 02606 if (keyPress >= TEXT(' ')) { 02607 /* 02608 * If this is in [a-z],[A-Z] and we are an ES_NUMBER 02609 * edit field, bail. 02610 */ 02611 if (ped->f40Compat && TestWF(ped->pwnd, EFNUMBER)) { 02612 if (!ECIsCharNumeric(ped, keyPress)) { 02613 goto IllegalChar; 02614 } 02615 } 02616 02617 goto DeleteSelection; 02618 } 02619 break; 02620 } 02621 02622 /* 02623 * Handle key codes 02624 */ 02625 switch(keyPress) { 02626 UINT msg; 02627 02628 // Ctrl+Z == Undo 02629 case 26: 02630 msg = WM_UNDO; 02631 goto SendEditingMessage; 02632 break; 02633 02634 // Ctrl+X == Cut 02635 case 24: 02636 if (ped->ichMinSel == ped->ichMaxSel) 02637 goto IllegalChar; 02638 else 02639 { 02640 msg = WM_CUT; 02641 goto SendEditingMessage; 02642 } 02643 break; 02644 02645 // Ctrl+C == Copy 02646 case 3: 02647 msg = WM_COPY; 02648 goto SendEditingMessage; 02649 break; 02650 02651 // Ctrl+V == Paste 02652 case 22: 02653 msg = WM_PASTE; 02654 SendEditingMessage: 02655 SendMessage(ped->hwnd, msg, 0, 0L); 02656 break; 02657 02658 case VK_BACK: 02659 // 02660 // Delete any selected text or delete character left if no sel 02661 // 02662 if (!updateText && ped->ichMinSel) 02663 { 02664 // 02665 // There was no selection to delete so we just delete 02666 // character left if available 02667 // 02668 ped->ichMinSel = MLMoveSelection(ped, ped->ichCaret, TRUE); 02669 MLDeleteText(ped); 02670 } 02671 break; 02672 02673 default: 02674 if (keyPress == VK_RETURN) 02675 if (ped->fAnsi) 02676 keyValue = 0x0A0D; 02677 else 02678 keyValue = 0x000A000D; 02679 02680 if ( keyPress >= TEXT(' ') 02681 || keyPress == VK_RETURN 02682 || keyPress == VK_TAB 02683 || keyPress == 0x1E // RS - Unicode block separator 02684 || keyPress == 0x1F // US - Unicode segment separator 02685 ) { 02686 02687 NtUserCallNoParam(SFI_ZZZHIDECURSORNOCAPTURE); 02688 if (ped->fAnsi) { 02689 // 02690 // check if it's a leading byte of double byte character 02691 // 02692 if (ECIsDBCSLeadByte(ped,(BYTE)keyPress)) { 02693 int DBCSkey; 02694 02695 if ((DBCSkey = DbcsCombine(ped->hwnd, keyPress)) != 0) 02696 keyValue = DBCSkey; 02697 } 02698 MLInsertText(ped, (LPSTR)&keyValue, HIBYTE(keyValue) ? 2 : 1, TRUE); 02699 } else 02700 MLInsertText(ped, (LPSTR)&keyValue, HIWORD(keyValue) ? 2 : 1, TRUE); 02701 } else { 02702 IllegalChar: 02703 NtUserMessageBeep(0); 02704 } 02705 break; 02706 } 02707 }

ICH MLDeleteText PED  ped  ) 
 

Definition at line 1367 of file editml.c.

References _IsWindowVisible(), BOOL, tagED::cch, tagED::chLines, CopyRect, ECDeleteText(), ECGetEditDC(), ECNextIch(), ECNotifyParent(), ECReleaseEditDC(), FALSE, tagED::fAnsi, tagED::fAutoVScroll, tagED::fDBCS, tagED::fDirty, FWINABLE, tagED::hwnd, ICH, tagED::ichMaxSel, tagED::ichMinSel, INT, tagED::lineHeight, max, MLBuildchLines(), MLDrawText(), MLEnsureCaretVisible(), MLIchToLine(), MLIchToXYPos(), MLIchToYPos(), MLShiftchLines(), MLUpdateiCaretLine(), NotifyWinEvent(), NtUserInvalidateRect(), NULL, tagED::pLpkEditCallout, tagED::pwnd, tagED::rcFmt, TRUE, tagED::wLeftMargin, and tagED::wRightMargin.

Referenced by ECImeComposition(), EditWndProc(), MLChar(), MLPasteText(), and MLReplaceSel().

01369 { 01370 ICH minSel = ped->ichMinSel; 01371 ICH maxSel = ped->ichMaxSel; 01372 ICH cchDelete; 01373 HDC hdc; 01374 int minSelLine; 01375 int maxSelLine; 01376 POINT xyPos; 01377 RECT rc; 01378 BOOL fFastDelete = FALSE; 01379 LONG hl; 01380 INT cchcount = 0; 01381 01382 /* 01383 * Get what line the min selection is on so that we can start rebuilding the 01384 * text from there if we delete anything. 01385 */ 01386 minSelLine = MLIchToLine(ped, minSel); 01387 maxSelLine = MLIchToLine(ped, maxSel); 01388 // 01389 // Calculate fFastDelete and cchcount 01390 // 01391 if (ped->fAnsi && ped->fDBCS) { 01392 if ((ped->fAutoVScroll) && 01393 (minSelLine == maxSelLine) && 01394 (ped->chLines[minSelLine] != minSel) && 01395 (ECNextIch(ped,NULL,minSel) == maxSel)) { 01396 01397 fFastDelete = TRUE; 01398 cchcount = ((maxSel - minSel) == 1) ? 0 : -1; 01399 } 01400 } else if (((maxSel - minSel) == 1) && (minSelLine == maxSelLine) && (ped->chLines[minSelLine] != minSel)) { 01401 if (!ped->fAutoVScroll) 01402 fFastDelete = FALSE; 01403 else 01404 fFastDelete = TRUE; 01405 } 01406 if (!(cchDelete = ECDeleteText(ped))) 01407 return (0); 01408 01409 /* 01410 * Start building lines at minsel line since caretline may be at the max sel 01411 * point. 01412 */ 01413 if (fFastDelete) { 01414 // 01415 // cchcount is (-1) if it's a double byte character 01416 // 01417 MLShiftchLines(ped, minSelLine + 1, -2 + cchcount); 01418 MLBuildchLines(ped, minSelLine, 1, TRUE, NULL, &hl); 01419 } else { 01420 MLBuildchLines(ped, max(minSelLine-1,0), -(int)cchDelete, FALSE, NULL, NULL); 01421 } 01422 01423 MLUpdateiCaretLine(ped); 01424 01425 ECNotifyParent(ped, EN_UPDATE); 01426 01427 if (_IsWindowVisible(ped->pwnd)) { 01428 01429 /* 01430 * Now update the screen to reflect the deletion 01431 */ 01432 hdc = ECGetEditDC(ped, FALSE); 01433 01434 /* 01435 * Otherwise just redraw starting at the line we just entered 01436 */ 01437 minSelLine = max(minSelLine-1,0); 01438 MLDrawText(ped, hdc, ped->chLines[minSelLine], 01439 fFastDelete ? hl : ped->cch, FALSE); 01440 01441 CopyRect(&rc, &ped->rcFmt); 01442 rc.left -= ped->wLeftMargin; 01443 rc.right += ped->wRightMargin; 01444 01445 if (ped->cch) { 01446 01447 /* 01448 * Clear from end of text to end of window. 01449 * 01450 * We only need the y position. Since with an LPK loaded 01451 * calculating the x position is an intensive job, just 01452 * call MLIchToYPos. 01453 */ 01454 if (ped->pLpkEditCallout) 01455 xyPos.y = MLIchToYPos(ped, ped->cch, FALSE); 01456 else 01457 MLIchToXYPos(ped, hdc, ped->cch, FALSE, &xyPos); 01458 rc.top = xyPos.y + ped->lineHeight; 01459 } 01460 01461 NtUserInvalidateRect(ped->hwnd, &rc, TRUE); 01462 ECReleaseEditDC(ped, hdc, FALSE); 01463 01464 MLEnsureCaretVisible(ped); 01465 } 01466 01467 ped->fDirty = TRUE; 01468 01469 ECNotifyParent(ped, EN_CHANGE); 01470 01471 if (cchDelete && FWINABLE()) 01472 NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, ped->hwnd, OBJID_CLIENT, INDEXID_CONTAINER); 01473 01474 return cchDelete; 01475 }

void MLDrawText PED  ped,
HDC  hdc,
ICH  ichStart,
ICH  ichEnd,
BOOL  fSelChange
 

Definition at line 3991 of file editml.c.

References BOOL, tagED::cbChar, tagED::cch, tagED::chLines, tagED::cLines, CopyRect, DWORD, ECAdjustIch(), ECAdjustIchNext(), ECGetBrush(), ECLock(), ECT_NORMAL, ECT_SELECTED, ECTabTheTextOut(), ECUnlock(), tagLPKEDITCALLOUT::EditDrawText, FALSE, tagED::fAnsi, tagED::fDBCS, tagED::fDisabled, tagED::fFocus, tagED::fNoHideSel, tagED::format, GetSysColor(), tagED::hwnd, ICH, tagED::ichLinesOnScreen, tagED::ichMaxSel, tagED::ichMinSel, tagED::ichScreenStart, INT, tagED::lineHeight, max, MAXCLIPENDPOS, min, MLCalcXOffset(), MLIchToLine(), MLIchToXYPos(), MLIchToYPos(), MLLine(), MLSetCaretPosition(), STRIPINFO::nCount, NtUserHideCaret(), NtUserInvalidateRect(), NtUserShowCaret(), tagED::pLpkEditCallout, tagED::rcFmt, TRUE, UINT, tagED::wLeftMargin, tagED::wMaxNegAcharPos, tagED::wMaxNegC, tagED::wMaxNegCcharPos, tagED::wRightMargin, tagED::xOffset, and STRIPINFO::XStartPos.

Referenced by MLChangeSelection(), MLDeleteText(), MLInsertText(), MLKillFocus(), MLPaint(), and MLSetFocus().

03997 { 03998 DWORD textColorSave; 03999 DWORD bkColorSave; 04000 PSTR pText; 04001 UINT wCurLine; 04002 UINT wEndLine; 04003 int xOffset; 04004 ICH LengthToDraw; 04005 ICH CurStripLength; 04006 ICH ichAttrib, ichNewStart; 04007 ICH ExtraLengthForNegA; 04008 ICH ichT; 04009 int iRemainingLengthInLine; 04010 int xStPos, xClipStPos, xClipEndPos, yPos; 04011 BOOL fFirstLineOfBlock = TRUE; 04012 BOOL fDrawEndOfLineStrip = FALSE; 04013 BOOL fDrawOnSameLine = FALSE; 04014 BOOL fSelected = FALSE; 04015 BOOL fLineBegins = FALSE; 04016 STRIPINFO NegCInfo; 04017 POINT pt; 04018 04019 // 04020 // Just return if nothing to draw 04021 if (!ped->ichLinesOnScreen) 04022 return; 04023 04024 ECGetBrush(ped, hdc); 04025 04026 // 04027 // Adjust the value of ichStart such that we need to draw only those lines 04028 // visible on the screen. 04029 // 04030 if ((UINT)ichStart < (UINT)ped->chLines[ped->ichScreenStart]) { 04031 ichStart = ped->chLines[ped->ichScreenStart]; 04032 if (ichStart > ichEnd) 04033 return; 04034 } 04035 04036 // Adjust the value of ichEnd such that we need to draw only those lines 04037 // visible on the screen. 04038 wCurLine = min(ped->ichScreenStart+ped->ichLinesOnScreen,ped->cLines-1); 04039 ichT = ped->chLines[wCurLine] + MLLine(ped, wCurLine); 04040 ichEnd = min(ichEnd, ichT); 04041 04042 wCurLine = MLIchToLine(ped, ichStart); // Starting line. 04043 wEndLine = MLIchToLine(ped, ichEnd); // Ending line. 04044 04045 UserAssert(ped->chLines[wCurLine] <= ped->cch + 1); 04046 UserAssert(ped->chLines[wEndLine] <= ped->cch + 1); 04047 04048 if (fSelChange && (GetBkMode(hdc) != OPAQUE)) 04049 { 04050 /* 04051 * if changing selection on a transparent edit control, just 04052 * draw those lines from scratch 04053 */ 04054 RECT rcStrip; 04055 CopyRect(&rcStrip, &ped->rcFmt); 04056 rcStrip.left -= ped->wLeftMargin; 04057 if (ped->pLpkEditCallout) { 04058 rcStrip.right += ped->wRightMargin; 04059 } 04060 rcStrip.top += (wCurLine - ped->ichScreenStart) * ped->lineHeight; 04061 rcStrip.bottom = rcStrip.top + ((wEndLine - wCurLine) + 1) * ped->lineHeight; 04062 NtUserInvalidateRect(ped->hwnd, &rcStrip, TRUE); 04063 return; 04064 } 04065 04066 // If it is either centered or right-justified, then draw the whole lines. 04067 // Also draw whole lines if the language pack is handling line layout. 04068 if ((ped->format != ES_LEFT) || (ped->pLpkEditCallout)) { 04069 ichStart = ped->chLines[wCurLine]; 04070 ichEnd = ped->chLines[wEndLine] + MLLine(ped, wEndLine); 04071 } 04072 04073 pText = ECLock(ped); 04074 04075 NtUserHideCaret(ped->hwnd); 04076 04077 // 04078 // If ichStart stays on Second byte of DBCS, we have to 04079 // adjust it. LiZ -- 5/5/93 04080 // 04081 if (ped->fAnsi && ped->fDBCS) { 04082 ichStart = ECAdjustIch( ped, pText, ichStart ); 04083 } 04084 UserAssert(ichStart <= ped->cch); 04085 UserAssert(ichEnd <= ped->cch); 04086 04087 while (ichStart <= ichEnd) { 04088 // Pass whole lines to the language pack to display with selection 04089 // marking and tab expansion. 04090 if (ped->pLpkEditCallout) { 04091 ped->pLpkEditCallout->EditDrawText( 04092 ped, hdc, pText + ped->cbChar*ichStart, 04093 MLLine(ped, wCurLine), 04094 (INT)ped->ichMinSel - (INT)ichStart, (INT)ped->ichMaxSel - (INT)ichStart, 04095 MLIchToYPos(ped, ichStart, FALSE)); 04096 } else { 04097 // xStPos: The starting Position where the string must be drawn. 04098 // xClipStPos: The starting position for the clipping rect for the block. 04099 // xClipEndPos: The ending position for the clipping rect for the block. 04100 04101 // Calculate the xyPos of starting point of the block. 04102 MLIchToXYPos(ped, hdc, ichStart, FALSE, &pt); 04103 xClipStPos = xStPos = pt.x; 04104 yPos = pt.y; 04105 04106 // The attributes of the block is the same as that of ichStart. 04107 ichAttrib = ichStart; 04108 04109 // If the current font has some negative C widths and if this is the 04110 // begining of a block, we must start drawing some characters before the 04111 // block to account for the negative C widths of the strip before the 04112 // current strip; In this case, reset ichStart and xStPos. 04113 04114 if (fFirstLineOfBlock && ped->wMaxNegC) { 04115 fFirstLineOfBlock = FALSE; 04116 ichNewStart = max(((int)(ichStart - ped->wMaxNegCcharPos)), ((int)ped->chLines[wCurLine])); 04117 04118 // If ichStart needs to be changed, then change xStPos also accordingly. 04119 if (ichNewStart != ichStart) { 04120 if (ped->fAnsi && ped->fDBCS) { 04121 // 04122 // Adjust DBCS alignment... 04123 // 04124 ichNewStart = ECAdjustIchNext( ped, pText, ichNewStart ); 04125 } 04126 MLIchToXYPos(ped, hdc, ichStart = ichNewStart, FALSE, &pt); 04127 xStPos = pt.x; 04128 } 04129 } 04130 04131 // Calc the number of characters remaining to be drawn in the current line. 04132 iRemainingLengthInLine = MLLine(ped, wCurLine) - 04133 (ichStart - ped->chLines[wCurLine]); 04134 04135 // If this is the last line of a block, we may not have to draw all the 04136 // remaining lines; We must draw only upto ichEnd. 04137 if (wCurLine == wEndLine) 04138 LengthToDraw = ichEnd - ichStart; 04139 else 04140 LengthToDraw = iRemainingLengthInLine; 04141 04142 // Find out how many pixels we indent the line for non-left-justified 04143 // formats 04144 if (ped->format != ES_LEFT) 04145 xOffset = MLCalcXOffset(ped, hdc, wCurLine); 04146 else 04147 xOffset = -((int)(ped->xOffset)); 04148 04149 // Check if this is the begining of a line. 04150 if (ichAttrib == ped->chLines[wCurLine]) { 04151 fLineBegins = TRUE; 04152 xClipStPos = ped->rcFmt.left - ped->wLeftMargin; 04153 } 04154 04155 // 04156 // The following loop divides this 'wCurLine' into strips based on the 04157 // selection attributes and draw them strip by strip. 04158 do { 04159 // 04160 // If ichStart is pointing at CRLF or CRCRLF, then iRemainingLength 04161 // could have become negative because MLLine does not include 04162 // CR and LF at the end of a line. 04163 // 04164 if (iRemainingLengthInLine < 0) // If Current line is completed, 04165 break; // go on to the next line. 04166 04167 // 04168 // Check if a part of the block is selected and if we need to 04169 // show it with a different attribute. 04170 // 04171 if (!(ped->ichMinSel == ped->ichMaxSel || 04172 ichAttrib >= ped->ichMaxSel || 04173 ichEnd < ped->ichMinSel || 04174 (!ped->fNoHideSel && !ped->fFocus))) { 04175 // 04176 // OK! There is a selection somewhere in this block! 04177 // Check if this strip has selection attribute. 04178 // 04179 if (ichAttrib < ped->ichMinSel) { 04180 fSelected = FALSE; // This strip is not selected 04181 04182 // Calculate the length of this strip with normal attribute. 04183 CurStripLength = min(ichStart+LengthToDraw, ped->ichMinSel)-ichStart; 04184 fLineBegins = FALSE; 04185 } else { 04186 // The current strip has the selection attribute. 04187 if (fLineBegins) { // Is it the first part of a line? 04188 // Then, draw the left margin area with normal attribute. 04189 fSelected = FALSE; 04190 CurStripLength = 0; 04191 xClipStPos = ped->rcFmt.left - ped->wLeftMargin; 04192 fLineBegins = FALSE; 04193 } else { 04194 // Else, draw the strip with selection attribute. 04195 fSelected = TRUE; 04196 CurStripLength = min(ichStart+LengthToDraw, ped->ichMaxSel)-ichStart; 04197 04198 // Select in the highlight colors. 04199 bkColorSave = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); 04200 if (!ped->fDisabled) 04201 textColorSave = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); 04202 } 04203 } 04204 } else { 04205 // The whole strip has no selection attributes. 04206 CurStripLength = LengthToDraw; 04207 } 04208 04209 // 04210 // Other than the current strip, do we still have anything 04211 // left to be drawn in the current line? 04212 // 04213 fDrawOnSameLine = (LengthToDraw != CurStripLength); 04214 04215 // 04216 // When we draw this strip, we need to draw some more characters 04217 // beyond the end of this strip to account for the negative A 04218 // widths of the characters that follow this strip. 04219 // 04220 ExtraLengthForNegA = min(iRemainingLengthInLine-CurStripLength, ped->wMaxNegAcharPos); 04221 04222 // 04223 // The blank strip at the end of the line needs to be drawn with 04224 // normal attribute irrespective of whether the line has selection 04225 // attribute or not. Hence, if the last strip of the line has selection 04226 // attribute, then this blank strip needs to be drawn separately. 04227 // Else, we can draw the blank strip along with the last strip. 04228 // 04229 04230 // Is this the last strip of the current line? 04231 if (iRemainingLengthInLine == (int)CurStripLength) { 04232 if (fSelected) { // Does this strip have selection attribute? 04233 // Then we need to draw the end of line strip separately. 04234 fDrawEndOfLineStrip = TRUE; // Draw the end of line strip. 04235 MLIchToXYPos(ped, hdc, ichStart+CurStripLength, TRUE, &pt); 04236 xClipEndPos = pt.x; 04237 } else { 04238 // 04239 // Set the xClipEndPos to a big value sothat the blank 04240 // strip will be drawn automatically when the last strip 04241 // is drawn. 04242 // 04243 xClipEndPos = MAXCLIPENDPOS; 04244 } 04245 } else { 04246 // 04247 // This is not the last strip of this line; So, set the ending 04248 // clip position accurately. 04249 // 04250 MLIchToXYPos(ped, hdc, ichStart+CurStripLength, FALSE, &pt); 04251 xClipEndPos = pt.x; 04252 } 04253 04254 // 04255 // Draw the current strip starting from xStPos, clipped to the area 04256 // between xClipStPos and xClipEndPos. Obtain "NegCInfo" and use it 04257 // in drawing the next strip. 04258 // 04259 ECTabTheTextOut(hdc, xClipStPos, xClipEndPos, 04260 xStPos, yPos, (LPSTR)(pText+ichStart*ped->cbChar), 04261 CurStripLength+ExtraLengthForNegA, ichStart, ped, 04262 ped->rcFmt.left+xOffset, fSelected ? ECT_SELECTED : ECT_NORMAL, &NegCInfo); 04263 04264 if (fSelected) { 04265 // 04266 // If this strip was selected, then the next strip won't have 04267 // selection attribute 04268 // 04269 fSelected = FALSE; 04270 SetBkColor(hdc, bkColorSave); 04271 if (!ped->fDisabled) 04272 SetTextColor(hdc, textColorSave); 04273 } 04274 04275 // Do we have one more strip to draw on the current line? 04276 if (fDrawOnSameLine || fDrawEndOfLineStrip) { 04277 int iLastDrawnLength; 04278 04279 // 04280 // Next strip's attribute is decided based on the char at ichAttrib 04281 // 04282 ichAttrib = ichStart + CurStripLength; 04283 04284 // 04285 // When drawing the next strip, start at a few chars before 04286 // the actual start to account for the Neg 'C' of the strip 04287 // just drawn. 04288 // 04289 iLastDrawnLength = CurStripLength +ExtraLengthForNegA - NegCInfo.nCount; 04290 // 04291 // Adjust DBCS alignment... 04292 // 04293 if (ped->fAnsi && ped->fDBCS) { 04294 ichNewStart = ECAdjustIch(ped,pText,ichStart+iLastDrawnLength); 04295 iLastDrawnLength = ichNewStart - ichStart; 04296 ichStart = ichNewStart; 04297 } else { 04298 ichStart += iLastDrawnLength; 04299 } 04300 LengthToDraw -= iLastDrawnLength; 04301 iRemainingLengthInLine -= iLastDrawnLength; 04302 04303 // 04304 // The start of clip rect for the next strip. 04305 // 04306 xStPos = NegCInfo.XStartPos; 04307 xClipStPos = xClipEndPos; 04308 } 04309 04310 // Draw the blank strip at the end of line seperately, if required. 04311 if (fDrawEndOfLineStrip) { 04312 ECTabTheTextOut(hdc, xClipStPos, MAXCLIPENDPOS, xStPos, yPos, 04313 (LPSTR)(pText+ichStart*ped->cbChar), LengthToDraw, ichStart, 04314 ped, ped->rcFmt.left+xOffset, ECT_NORMAL, &NegCInfo); 04315 04316 fDrawEndOfLineStrip = FALSE; 04317 } 04318 } 04319 while(fDrawOnSameLine); // do while loop ends here. 04320 } 04321 04322 // Let us move on to the next line of this block to be drawn. 04323 wCurLine++; 04324 if (ped->cLines > wCurLine) 04325 ichStart = ped->chLines[wCurLine]; 04326 else 04327 ichStart = ichEnd+1; // We have reached the end of the text. 04328 } // while loop ends here 04329 04330 ECUnlock(ped); 04331 04332 NtUserShowCaret(ped->hwnd); 04333 MLSetCaretPosition(ped, hdc); 04334 }

LRESULT MLEditWndProc HWND  hwnd,
PED  ped,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 3457 of file editml.c.

References _IsWindowVisible(), abs, tagED::aveCharWidth, BOOL, tagED::cch, DefWindowProcWorker(), DWORD, ECEmptyUndo(), ECGetCaretWidth, ECGetEditDC(), ECInOutReconversionMode(), ECLock(), ECReleaseEditDC(), ECSize(), ECUnlock(), ECUpdateFormat(), tagLPKEDITCALLOUT::EditCreateCaret, EnterReaderModeHelper(), tagED::f40Compat, FALSE, tagED::fAnsi, tagED::fDisabled, tagED::fFocus, FillWindow, tagED::fInDialogBox, tagED::fMouseDown, tagED::fReadOnly, gcWheelDelta, gpsi, tagED::hText, tagED::hwnd, tagED::hwndParent, ICH, tagED::ichLinesOnScreen, tagED::ichScreenStart, IDSYS_SCROLL, INT, L, tagED::lineHeight, max, min, MLBuildchLines(), MLChar(), MLCreate(), MLEnsureCaretVisible(), MLGetLine(), MLIchToLine(), MLIchToXYPos(), MLInsertCrCrLf(), MLKeyDown(), MLKillFocus(), MLLineIndex(), MLLineLength(), MLMouseMotion(), MLMouseToIch(), MLPaint(), MLPasteText(), MLReplaceSel(), MLScroll(), MLSetCaretPosition(), MLSetFocus(), MLSetHandle(), MLSetSelection(), MLSetTabStops(), MLStripCrCrLf(), MLUndo(), NtUserBeginPaint(), NtUserDestroyCaret, NtUserEndPaint(), NtUserHideCaret(), NtUserKillSystemTimer, NtUserShowCaret(), NULL, tagED::pLpkEditCallout, tagED::prevKeys, tagED::ptPrevMouse, Pundo, tagED::pwnd, tagED::rcFmt, RedrawWindow, SendMessage(), SYS_ALTERNATE, TRUE, UINT, and WM_SYSTIMER.

Referenced by ECClearText(), and EditWndProc().

03463 { 03464 HDC hdc; 03465 PAINTSTRUCT ps; 03466 LPRECT lprc; 03467 POINT pt; 03468 DWORD windowstyle; 03469 03470 switch (message) { 03471 03472 case WM_INPUTLANGCHANGE: 03473 if (ped && ped->fFocus && ped->pLpkEditCallout) { 03474 NtUserHideCaret(hwnd); 03475 hdc = ECGetEditDC(ped, TRUE); 03476 NtUserDestroyCaret(); 03477 ped->pLpkEditCallout->EditCreateCaret (ped, hdc, ECGetCaretWidth(), ped->lineHeight, (UINT)lParam); 03478 MLSetCaretPosition(ped, hdc); 03479 ECReleaseEditDC(ped, hdc, TRUE); 03480 NtUserShowCaret(hwnd); 03481 } 03482 goto PassToDefaultWindowProc; 03483 03484 03485 case WM_STYLECHANGED: 03486 if (ped && ped->pLpkEditCallout) { 03487 switch (wParam) { 03488 03489 case GWL_STYLE: 03490 ECUpdateFormat(ped, 03491 ((LPSTYLESTRUCT)lParam)->styleNew, 03492 GetWindowLong(ped->hwnd, GWL_EXSTYLE)); 03493 return 1L; 03494 03495 case GWL_EXSTYLE: 03496 ECUpdateFormat(ped, 03497 GetWindowLong(ped->hwnd, GWL_STYLE), 03498 ((LPSTYLESTRUCT)lParam)->styleNew); 03499 return 1L; 03500 } 03501 } 03502 03503 goto PassToDefaultWindowProc; 03504 03505 case WM_CHAR: 03506 03507 /* 03508 * wParam - the value of the key 03509 * lParam - modifiers, repeat count etc (not used) 03510 */ 03511 MLChar(ped, (UINT)wParam, 0); 03512 break; 03513 03514 case WM_ERASEBKGND: { 03515 HBRUSH hbr; 03516 03517 // USE SAME RULES AS IN ECGetBrush() 03518 if (ped->f40Compat && 03519 (ped->fReadOnly || ped->fDisabled)) 03520 hbr = (HBRUSH) CTLCOLOR_STATIC; 03521 else 03522 hbr = (HBRUSH) CTLCOLOR_EDIT; 03523 03524 FillWindow(ped->hwndParent, hwnd, (HDC)wParam, hbr); 03525 } 03526 return ((LONG)TRUE); 03527 03528 case WM_GETDLGCODE: { 03529 LONG code = DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS | DLGC_WANTALLKEYS; 03530 03531 /* 03532 ** !!! JEFFBOG HACK !!! 03533 ** Only set Dialog Box Flag if GETDLGCODE message is generated by 03534 ** IsDialogMessage -- if so, the lParam will be a pointer to the 03535 ** message structure passed to IsDialogMessage; otherwise, lParam 03536 ** will be NULL. Reason for the HACK alert: the wParam & lParam 03537 ** for GETDLGCODE is still not clearly defined and may end up 03538 ** changing in a way that would throw this off 03539 ** 03540 */ 03541 if (lParam) 03542 ped->fInDialogBox = TRUE; // Mark ML edit ctrl as in a dialog box 03543 03544 /* 03545 ** If this is a WM_SYSCHAR message generated by the UNDO keystroke 03546 ** we want this message so we can EAT IT in "case WM_SYSCHAR:" 03547 */ 03548 if (lParam && (((LPMSG)lParam)->message == WM_SYSCHAR) && 03549 ((DWORD)((LPMSG)lParam)->lParam & SYS_ALTERNATE) && 03550 ((WORD)wParam == VK_BACK)) 03551 code |= DLGC_WANTMESSAGE; 03552 return code; 03553 } 03554 03555 case EM_SCROLL: 03556 message = WM_VSCROLL; 03557 03558 /* 03559 * FALL THROUGH 03560 */ 03561 case WM_HSCROLL: 03562 case WM_VSCROLL: 03563 return MLScroll(ped, (message==WM_VSCROLL), LOWORD(wParam), HIWORD(wParam), TRUE); 03564 03565 case WM_MOUSEWHEEL: 03566 /* 03567 * Don't handle zoom and datazoom. 03568 */ 03569 if (wParam & (MK_SHIFT | MK_CONTROL)) { 03570 goto PassToDefaultWindowProc; 03571 } 03572 03573 gcWheelDelta -= (short) HIWORD(wParam); 03574 windowstyle = ped->pwnd->style; 03575 if ( abs(gcWheelDelta) >= WHEEL_DELTA && 03576 gpsi->ucWheelScrollLines > 0 && 03577 (windowstyle & (WS_VSCROLL | WS_HSCROLL))) { 03578 03579 int cLineScroll; 03580 BOOL fVert; 03581 int cPage; 03582 03583 if (windowstyle & WS_VSCROLL) { 03584 fVert = TRUE; 03585 cPage = ped->ichLinesOnScreen; 03586 } else { 03587 fVert = FALSE; 03588 cPage = (ped->rcFmt.right - ped->rcFmt.left) / ped->aveCharWidth; 03589 } 03590 03591 /* 03592 * Limit a roll of one (1) WHEEL_DELTA to scroll one (1) page. 03593 */ 03594 cLineScroll = (int) min( 03595 (UINT) (max(1, (cPage - 1))), 03596 gpsi->ucWheelScrollLines); 03597 03598 cLineScroll *= (gcWheelDelta / WHEEL_DELTA); 03599 UserAssert(cLineScroll != 0); 03600 gcWheelDelta = gcWheelDelta % WHEEL_DELTA; 03601 MLScroll(ped, fVert, EM_LINESCROLL, cLineScroll, TRUE); 03602 } 03603 03604 break; 03605 03606 case WM_KEYDOWN: 03607 03608 /* 03609 * wParam - virt keycode of the given key 03610 * lParam - modifiers such as repeat count etc. (not used) 03611 */ 03612 MLKeyDown(ped, (UINT)wParam, 0); 03613 break; 03614 03615 case WM_KILLFOCUS: 03616 03617 /* 03618 * wParam - handle of the window that receives the input focus 03619 * lParam - not used 03620 */ 03621 MLKillFocus(ped); 03622 break; 03623 03624 case WM_CAPTURECHANGED: 03625 // 03626 // wParam -- unused 03627 // lParam -- hwnd of window gaining capture. 03628 // 03629 if (ped->fMouseDown) { 03630 // 03631 // We don't change the caret pos here. If this is happening 03632 // due to button up, then we'll change the pos in the 03633 // handler after ReleaseCapture(). Otherwise, just end 03634 // gracefully because someone else has stolen capture out 03635 // from under us. 03636 // 03637 03638 ped->fMouseDown = FALSE; 03639 NtUserKillSystemTimer(ped->hwnd, IDSYS_SCROLL); 03640 } 03641 break; 03642 03643 case WM_SYSTIMER: 03644 03645 /* 03646 * This allows us to automatically scroll if the user holds the mouse 03647 * outside the edit control window. We simulate mouse moves at timer 03648 * intervals set in MouseMotionHandler. 03649 */ 03650 if (ped->fMouseDown) 03651 MLMouseMotion(ped, WM_MOUSEMOVE, ped->prevKeys, &ped->ptPrevMouse); 03652 break; 03653 03654 case WM_MBUTTONDOWN: 03655 EnterReaderModeHelper(ped->hwnd); 03656 break; 03657 03658 case WM_MOUSEMOVE: 03659 UserAssert(ped->fMouseDown); 03660 03661 /* 03662 * FALL THROUGH 03663 */ 03664 case WM_LBUTTONDBLCLK: 03665 case WM_LBUTTONDOWN: 03666 case WM_LBUTTONUP: 03667 /* 03668 * wParam - contains a value that indicates which virtual keys are down 03669 lParam - contains x and y coords of the mouse cursor 03670 */ 03671 POINTSTOPOINT(pt, lParam); 03672 MLMouseMotion(ped, message, (UINT)wParam, &pt); 03673 break; 03674 03675 case WM_CREATE: 03676 03677 /* 03678 * wParam - handle to window being created 03679 * lParam - points to a CREATESTRUCT that contains copies of parameters 03680 * passed to the CreateWindow function. 03681 */ 03682 return (MLCreate(ped, (LPCREATESTRUCT)lParam)); 03683 03684 case WM_PRINTCLIENT: 03685 MLPaint(ped, (HDC) wParam, NULL); 03686 break; 03687 03688 case WM_PAINT: 03689 /* 03690 * wParam - can be hdc from subclassed paint 03691 lParam - not used 03692 */ 03693 if (wParam) { 03694 hdc = (HDC) wParam; 03695 lprc = NULL; 03696 } else { 03697 hdc = NtUserBeginPaint(ped->hwnd, &ps); 03698 lprc = &ps.rcPaint; 03699 } 03700 03701 if (_IsWindowVisible(ped->pwnd)) 03702 MLPaint(ped, hdc, lprc); 03703 03704 if (!wParam) 03705 NtUserEndPaint(ped->hwnd, &ps); 03706 break; 03707 03708 case WM_PASTE: 03709 03710 /* 03711 * wParam - not used 03712 lParam - not used 03713 */ 03714 if (!ped->fReadOnly) 03715 MLPasteText(ped); 03716 break; 03717 03718 case WM_SETFOCUS: 03719 03720 /* 03721 * wParam - handle of window that loses the input focus (may be NULL) 03722 lParam - not used 03723 */ 03724 MLSetFocus(ped); 03725 break; 03726 03727 case WM_SIZE: 03728 03729 /* 03730 * wParam - defines the type of resizing fullscreen, sizeiconic, 03731 sizenormal etc. 03732 lParam - new width in LOWORD, new height in HIGHWORD of client area 03733 */ 03734 ECSize(ped, NULL, TRUE); 03735 break; 03736 03737 case EM_FMTLINES: 03738 03739 /* 03740 * wParam - indicates disposition of end-of-line chars. If non 03741 * zero, the chars CR CR LF are placed at the end of a word 03742 * wrapped line. If wParam is zero, the end of line chars are 03743 * removed. This is only done when the user gets a handle (via 03744 * EM_GETHANDLE) to the text. lParam - not used. 03745 */ 03746 if (wParam) 03747 MLInsertCrCrLf(ped); 03748 else 03749 MLStripCrCrLf(ped); 03750 MLBuildchLines(ped, 0, 0, FALSE, NULL, NULL); 03751 return (LONG)(wParam != 0); 03752 03753 case EM_GETHANDLE: 03754 03755 /* 03756 * wParam - not used 03757 lParam - not used 03758 */ 03759 03760 /* 03761 * Returns a handle to the edit control's text. 03762 */ 03763 03764 /* 03765 * Null terminate the string. Note that we are guaranteed to have the 03766 * memory for the NULL since ECInsertText allocates an extra 03767 * WCHAR for the NULL terminator. 03768 */ 03769 03770 if (ped->fAnsi) 03771 *(ECLock(ped) + ped->cch) = 0; 03772 else 03773 *((LPWSTR)ECLock(ped) + ped->cch) = 0; 03774 ECUnlock(ped); 03775 return ((LRESULT)ped->hText); 03776 03777 case EM_GETLINE: 03778 03779 /* 03780 * wParam - line number to copy (0 is first line) 03781 * lParam - buffer to copy text to. First WORD is max # of bytes to 03782 * copy 03783 */ 03784 return MLGetLine(ped, (ICH)wParam, (ICH)*(WORD UNALIGNED *)lParam, (LPSTR)lParam); 03785 03786 case EM_LINEFROMCHAR: 03787 03788 /* 03789 * wParam - Contains the index value for the desired char in the text 03790 * of the edit control. These are 0 based. 03791 * lParam - not used 03792 */ 03793 return (LRESULT)MLIchToLine(ped, (ICH)wParam); 03794 03795 case EM_LINEINDEX: 03796 03797 /* 03798 * wParam - specifies the desired line number where the number of the 03799 * first line is 0. If linenumber = 0, the line with the caret is used. 03800 * lParam - not used. 03801 * This function return s the number of character positions that occur 03802 * preceeding the first char in a given line. 03803 */ 03804 return (LRESULT)MLLineIndex(ped, (ICH)wParam); 03805 03806 case EM_LINELENGTH: 03807 03808 /* 03809 * wParam - specifies the character index of a character in the 03810 specified line, where the first line is 0. If -1, the length 03811 of the current line (with the caret) is return ed not including the 03812 length of any selected text. 03813 lParam - not used 03814 */ 03815 return (LRESULT)MLLineLength(ped, (ICH)wParam); 03816 03817 case EM_LINESCROLL: 03818 03819 /* 03820 * wParam - not used 03821 lParam - Contains the number of lines and char positions to scroll 03822 */ 03823 MLScroll(ped, TRUE, EM_LINESCROLL, (INT)lParam, TRUE); 03824 MLScroll(ped, FALSE, EM_LINESCROLL, (INT)wParam, TRUE); 03825 break; 03826 03827 case EM_REPLACESEL: 03828 03829 /* 03830 * wParam - flag for 4.0+ apps saying whether to clear undo 03831 lParam - Points to a null terminated replacement text. 03832 */ 03833 MLReplaceSel(ped, (LPSTR)lParam); 03834 if (!ped->f40Compat || !wParam) 03835 ECEmptyUndo(Pundo(ped)); 03836 break; 03837 03838 case EM_SETHANDLE: 03839 03840 /* 03841 * wParam - contains a handle to the text buffer 03842 lParam - not used 03843 */ 03844 MLSetHandle(ped, (HANDLE)wParam); 03845 break; 03846 03847 case EM_SETRECT: 03848 case EM_SETRECTNP: 03849 03850 // 03851 // wParamLo -- not used 03852 // lParam -- LPRECT with new formatting area 03853 // 03854 ECSize(ped, (LPRECT) lParam, (message != EM_SETRECTNP)); 03855 break; 03856 03857 case EM_SETSEL: 03858 03859 /* 03860 * wParam - Under 3.1, specifies if we should scroll caret into 03861 * view or not. 0 == scroll into view. 1 == don't scroll 03862 * lParam - starting pos in lowword ending pos in high word 03863 * 03864 * Under Win32, wParam is the starting pos, lParam is the 03865 * ending pos, and the caret is not scrolled into view. 03866 * The message EM_SCROLLCARET forces the caret to be scrolled 03867 * into view. 03868 */ 03869 MLSetSelection(ped, TRUE, (ICH)wParam, (ICH)lParam); 03870 break; 03871 03872 case EM_SCROLLCARET: 03873 03874 /* 03875 * Scroll caret into view 03876 */ 03877 MLEnsureCaretVisible(ped); 03878 break; 03879 03880 case EM_GETFIRSTVISIBLELINE: 03881 03882 /* 03883 * Returns the first visible line for multiline edit controls. 03884 */ 03885 return (LONG)ped->ichScreenStart; 03886 03887 case WM_SYSKEYDOWN: 03888 if (((WORD)wParam == VK_BACK) && ((DWORD)lParam & SYS_ALTERNATE)) { 03889 SendMessage(ped->hwnd, EM_UNDO, 0, 0L); 03890 break; 03891 } 03892 goto PassToDefaultWindowProc; 03893 03894 case WM_UNDO: 03895 case EM_UNDO: 03896 return MLUndo(ped); 03897 03898 case EM_SETTABSTOPS: 03899 03900 /* 03901 * This sets the tab stop positions for multiline edit controls. 03902 * wParam - Number of tab stops 03903 * lParam - Far ptr to a UINT array containing the Tab stop positions 03904 */ 03905 return MLSetTabStops(ped, (int)wParam, (LPINT)lParam); 03906 03907 case EM_POSFROMCHAR: 03908 // 03909 // wParam -- char index in text 03910 // lParam -- not used 03911 // This function returns the (x,y) position of the character 03912 // 03913 case EM_CHARFROMPOS: 03914 // 03915 // wParam -- unused 03916 // lParam -- pt in client coordinates 03917 // This function returns 03918 // LOWORD: the position of the closest character 03919 // to the passed in point. Beware of 03920 // points not actually in the edit client... 03921 // HIWORD: the index of the line the char is on 03922 // 03923 { 03924 LONG xyPos; 03925 LONG line; 03926 03927 hdc = ECGetEditDC(ped, TRUE); 03928 03929 if (message == EM_POSFROMCHAR) { 03930 MLIchToXYPos(ped, hdc, (ICH)wParam, FALSE, &pt); 03931 xyPos = MAKELONG(pt.x, pt.y); 03932 } else { 03933 POINTSTOPOINT(pt, lParam); 03934 xyPos = MLMouseToIch(ped, hdc, &pt, &line); 03935 xyPos = MAKELONG(xyPos, line); 03936 } 03937 03938 ECReleaseEditDC(ped, hdc, TRUE); 03939 return((LRESULT)xyPos); 03940 break; 03941 } 03942 03943 case WM_SETREDRAW: 03944 DefWindowProcWorker(ped->pwnd, message, wParam, lParam, FALSE); 03945 if (wParam) { 03946 03947 /* 03948 * Backwards compatability hack needed so that winraid's edit 03949 * controls work fine. 03950 */ 03951 RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME); 03952 } 03953 break; 03954 03955 #if LATER 03956 case WM_IME_ENDCOMPOSITION: 03957 ECInOutReconversionMode(ped, FALSE); 03958 break; 03959 #endif 03960 03961 default: 03962 PassToDefaultWindowProc: 03963 return DefWindowProcWorker(ped->pwnd, message, wParam, lParam, ped->fAnsi); 03964 } 03965 03966 return 1L; 03967 } /* MLEditWndProc */

BOOL MLEnsureCaretVisible PED  ped  ) 
 

Definition at line 3379 of file editml.c.

References _IsWindowVisible(), tagED::aveCharWidth, BOOL, tagED::chLines, tagED::cLines, ECGetEditDC(), ECReleaseEditDC(), FALSE, tagED::fAutoHScroll, tagED::fAutoVScroll, tagED::iCaretLine, tagED::ichCaret, tagED::ichLinesOnScreen, tagED::ichScreenStart, tagED::maxPixelWidth, MLIchToXYPos(), MLScroll(), tagED::pwnd, tagED::rcFmt, TRUE, and UINT.

Referenced by MLDeleteText(), MLEditWndProc(), MLInsertText(), MLKeyDown(), MLMouseMotion(), MLSetFocus(), MLSetSelection(), and MLSetTabStops().

03381 { 03382 UINT iLineMax; 03383 int xposition; 03384 BOOL fPrevLine; 03385 HDC hdc; 03386 BOOL fVScroll = FALSE; 03387 BOOL fHScroll = FALSE; 03388 03389 if (_IsWindowVisible(ped->pwnd)) { 03390 int iAmt; 03391 int iFmtWidth = ped->rcFmt.right - ped->rcFmt.left; 03392 03393 if (ped->fAutoVScroll) { 03394 iLineMax = ped->ichScreenStart + ped->ichLinesOnScreen - 1; 03395 03396 if (fVScroll = (ped->iCaretLine > iLineMax)) 03397 iAmt = iLineMax; 03398 else if (fVScroll = (ped->iCaretLine < ped->ichScreenStart)) 03399 iAmt = ped->ichScreenStart; 03400 03401 if (fVScroll) 03402 MLScroll(ped, TRUE, EM_LINESCROLL, ped->iCaretLine - iAmt, TRUE); 03403 } 03404 03405 if (ped->fAutoHScroll && ((int) ped->maxPixelWidth > iFmtWidth)) { 03406 POINT pt; 03407 /* Get the current position of the caret in pixels */ 03408 if ((UINT) (ped->cLines - 1) != ped->iCaretLine && 03409 ped->ichCaret == ped->chLines[ped->iCaretLine + 1]) 03410 fPrevLine = TRUE; 03411 else 03412 fPrevLine = FALSE; 03413 03414 hdc = ECGetEditDC(ped,TRUE); 03415 MLIchToXYPos(ped, hdc, ped->ichCaret, fPrevLine, &pt); 03416 ECReleaseEditDC(ped, hdc, TRUE); 03417 xposition = pt.x; 03418 03419 // Remember, MLIchToXYPos returns coordinates with respect to the 03420 // top left pixel displayed on the screen. Thus, if xPosition < 0, 03421 // it means xPosition is less than current ped->xOffset. 03422 03423 iFmtWidth /= 3; 03424 if (fHScroll = (xposition < ped->rcFmt.left)) 03425 // scroll to the left 03426 iAmt = ped->rcFmt.left + iFmtWidth; 03427 else if (fHScroll = (xposition > ped->rcFmt.right)) 03428 // scroll to the right 03429 iAmt = ped->rcFmt.right - iFmtWidth; 03430 03431 if (fHScroll) 03432 MLScroll(ped, FALSE, EM_LINESCROLL, (xposition - iAmt) / ped->aveCharWidth, TRUE); 03433 } 03434 } 03435 return(fVScroll); 03436 }

UINT MLGetLineWidth HDC  hdc,
LPSTR  lpstr,
int  nCnt,
PED  ped
 

Definition at line 40 of file editml.c.

References ECT_CALC, ECTabTheTextOut(), NULL, and UINT.

Referenced by MLBuildchLines(), MLCalcXOffset(), MLIchToXYPos(), and MLMouseToIch().

00041 { 00042 return(ECTabTheTextOut(hdc, 0, 0, 0, 0, lpstr, nCnt, 0, ped, 0, ECT_CALC, NULL)); 00043 }

int MLIchToLine PED  ped,
ICH  ich
 

Definition at line 443 of file editml.c.

References tagED::chLines, tagED::cLines, ICH, tagED::ichMinSel, and max.

Referenced by MLDeleteText(), MLDrawText(), MLEditWndProc(), MLIchToXYPos(), MLIchToYPos(), MLInsertText(), MLKeyDown(), MLLineLength(), MLSetSelection(), and MLUpdateiCaretLine().

00446 { 00447 int iLo, iHi, iLine; 00448 00449 iLo = 0; 00450 iHi = ped->cLines; 00451 00452 if (ich == (ICH)-1) 00453 ich = ped->ichMinSel; 00454 00455 while (iLo < iHi - 1) { 00456 iLine = max((iHi - iLo)/2, 1) + iLo; 00457 00458 if (ped->chLines[iLine] > ich) { 00459 iHi = iLine; 00460 } else { 00461 iLo = iLine; 00462 } 00463 } 00464 00465 return iLo; 00466 }

void MLIchToXYPos PED  ped,
HDC  hdc,
ICH  ich,
BOOL  prevLine,
LPPOINT  ppt
 

Definition at line 553 of file editml.c.

References AWCOMPARECHAR, tagED::cbChar, tagED::cch, tagED::chLines, DWORD, ECLock(), ECUnlock(), tagLPKEDITCALLOUT::EditIchToXY, tagED::fAnsi, tagED::format, ICH, tagED::ichScreenStart, tagED::lineHeight, MLCalcXOffset(), MLGetLineWidth(), MLIchToLine(), MLLine(), tagED::pLpkEditCallout, tagED::rcFmt, and tagED::xOffset.

Referenced by MLDeleteText(), MLDrawText(), MLEditWndProc(), MLEnsureCaretVisible(), MLInsertText(), MLKeyDown(), and MLSetCaretPosition().

00559 { 00560 int iline; 00561 ICH cch; 00562 int xPosition, yPosition; 00563 int xOffset; 00564 00565 /* 00566 * For horizontal scroll displacement on left justified text and 00567 * for indent on centered or right justified text 00568 */ 00569 PSTR pText, pTextStart, pLineStart; 00570 00571 /* 00572 * Determine what line the character is on 00573 */ 00574 iline = MLIchToLine(ped, ich); 00575 00576 /* 00577 * Calc. the yPosition now. Note that this may change by the height of one 00578 * char if the prevLine flag is set and the ICH is at the beginning of a 00579 * line. 00580 */ 00581 yPosition = (iline - ped->ichScreenStart) * ped->lineHeight + ped->rcFmt.top; 00582 00583 /* 00584 * Now determine the xPosition of the character 00585 */ 00586 pTextStart = ECLock(ped); 00587 00588 if (prevLine && iline && (ich == ped->chLines[iline]) && 00589 (!AWCOMPARECHAR(ped, pTextStart + (ich - 2) * ped->cbChar, 0x0D) || 00590 !AWCOMPARECHAR(ped, pTextStart + (ich - 1) * ped->cbChar, 0x0A))) { 00591 00592 /* 00593 * First char in the line. We want text extent upto end of the previous 00594 * line if we aren't at the 0th line. 00595 */ 00596 iline--; 00597 00598 yPosition = yPosition - ped->lineHeight; 00599 pLineStart = pTextStart + ped->chLines[iline] * ped->cbChar; 00600 00601 /* 00602 * Note that we are taking the position in front of any CRLFs in the 00603 * text. 00604 */ 00605 cch = MLLine(ped, iline); 00606 00607 } else { 00608 00609 pLineStart = pTextStart + ped->chLines[iline] * ped->cbChar; 00610 pText = pTextStart + ich * ped->cbChar; 00611 00612 /* 00613 * Strip off CRLF or CRCRLF. Note that we may be pointing to a CR but in 00614 * which case we just want to strip off a single CR or 2 CRs. 00615 */ 00616 00617 /* 00618 * We want pText to point to the first CR at the end of the line if 00619 * there is one. Thus, we will get an xPosition to the right of the last 00620 * visible char on the line otherwise we will be to the left of 00621 * character ich. 00622 */ 00623 00624 /* 00625 * Check if we at the end of text 00626 */ 00627 if (ich < ped->cch) { 00628 if (ped->fAnsi) { 00629 if (ich && *(WORD UNALIGNED *)(pText - 1) == 0x0A0D) { 00630 pText--; 00631 if (ich > 2 && *(pText - 1) == 0x0D) 00632 pText--; 00633 } 00634 } else { 00635 LPWSTR pwText = (LPWSTR)pText; 00636 00637 if (ich && *(DWORD UNALIGNED *)(pwText - 1) == 0x000A000D) { 00638 pwText--; 00639 if (ich > 2 && *(pwText - 1) == 0x0D) 00640 pwText--; 00641 } 00642 pText = (LPSTR)pwText; 00643 } 00644 } 00645 00646 if (pText < pLineStart) 00647 pText = pLineStart; 00648 00649 cch = (ICH)(pText - pLineStart)/ped->cbChar; 00650 } 00651 00652 /* 00653 * Find out how many pixels we indent the line for funny formats 00654 */ 00655 if (ped->pLpkEditCallout) { 00656 /* 00657 * Must find position at start of character offset cch from start of line. 00658 * This depends on the layout and the reading order 00659 */ 00660 xPosition = ped->pLpkEditCallout->EditIchToXY( 00661 ped, hdc, pLineStart, MLLine(ped, iline), cch); 00662 } else { 00663 if (ped->format != ES_LEFT) { 00664 xOffset = MLCalcXOffset(ped, hdc, iline); 00665 } else { 00666 xOffset = -(int)ped->xOffset; 00667 } 00668 00669 xPosition = ped->rcFmt.left + xOffset + 00670 MLGetLineWidth(hdc, pLineStart, cch, ped); 00671 } 00672 00673 ECUnlock(ped); 00674 ppt->x = xPosition; 00675 ppt->y = yPosition; 00676 return ; 00677 }

INT MLIchToYPos PED  ped,
ICH  ich,
BOOL  prevLine
 

Definition at line 502 of file editml.c.

References AWCOMPARECHAR, tagED::cbChar, tagED::chLines, ECLock(), ECUnlock(), tagED::ichScreenStart, INT, tagED::lineHeight, MLIchToLine(), and tagED::rcFmt.

Referenced by MLDeleteText(), MLDrawText(), and MLInsertText().

00506 { 00507 int iline; 00508 int yPosition; 00509 PSTR pText; 00510 00511 /* 00512 * Determine what line the character is on 00513 */ 00514 iline = MLIchToLine(ped, ich); 00515 00516 /* 00517 * Calc. the yPosition now. Note that this may change by the height of one 00518 * char if the prevLine flag is set and the ICH is at the beginning of a 00519 * line. 00520 */ 00521 yPosition = (iline - ped->ichScreenStart) * ped->lineHeight + ped->rcFmt.top; 00522 00523 pText = ECLock(ped); 00524 if (prevLine && iline && (ich == ped->chLines[iline]) && 00525 (!AWCOMPARECHAR(ped, pText + (ich - 2) * ped->cbChar, 0x0D) || 00526 !AWCOMPARECHAR(ped, pText + (ich - 1) * ped->cbChar, 0x0A))) { 00527 00528 /* 00529 * First char in the line. We want Y position of the previous 00530 * line if we aren't at the 0th line. 00531 */ 00532 iline--; 00533 00534 yPosition = yPosition - ped->lineHeight; 00535 } 00536 ECUnlock(ped); 00537 00538 return yPosition; 00539 }

BOOL MLInsertchLine PED  ped,
ICH  iLine,
ICH  ich,
BOOL  fUserTyping
 

Definition at line 1487 of file editml.c.

References BOOL, tagED::chLines, tagED::cLines, DWORD, ECNotifyParent(), FALSE, LINEBUMP, LPICH, TRUE, UserLocalReAlloc, and UserLocalSize.

Referenced by MLBuildchLines().

01492 { 01493 DWORD dwSize; 01494 01495 if (fUserTyping && iLine < ped->cLines) { 01496 ped->chLines[iLine] = ich; 01497 return (TRUE); 01498 } 01499 01500 dwSize = (ped->cLines + 2) * sizeof(int); 01501 01502 if (dwSize > UserLocalSize(ped->chLines)) { 01503 LPICH hResult; 01504 /* 01505 * Grow the line index buffer 01506 */ 01507 dwSize += LINEBUMP * sizeof(int); 01508 hResult = (LPICH)UserLocalReAlloc(ped->chLines, dwSize, 0); 01509 01510 if (!hResult) { 01511 ECNotifyParent(ped, EN_ERRSPACE); 01512 return FALSE; 01513 } 01514 ped->chLines = hResult; 01515 } 01516 01517 /* 01518 * Move indices starting at iLine up 01519 */ 01520 if (ped->cLines != iLine) 01521 RtlMoveMemory(&ped->chLines[iLine + 1], &ped->chLines[iLine], 01522 (ped->cLines - iLine) * sizeof(int)); 01523 ped->cLines++; 01524 01525 ped->chLines[iLine] = ich; 01526 return TRUE; 01527 }

ICH MLInsertText PED  ped,
LPSTR  lpText,
ICH  cchInsert,
BOOL  fUserTyping
 

Definition at line 1040 of file editml.c.

References _IsWindowVisible(), BOOL, tagED::cbChar, tagED::cch, tagED::cchTextMax, tagED::chLines, tagED::cLines, CopyRect, DWORD, ECAdjustIch(), ECEmptyUndo(), ECGetEditDC(), ECInsertText(), ECLock(), ECNotifyParent(), ECReleaseEditDC(), ECSaveUndo(), FALSE, tagED::fAnsi, tagED::fAutoVScroll, tagED::fDBCS, tagED::fDirty, tagED::format, tagED::fRtoLReading, FWINABLE, tagED::fWrap, tagED::hwnd, tagED::iCaretLine, ICH, tagED::ichCaret, tagED::ichLinesOnScreen, tagED::ichScreenStart, IsWindow(), tagED::lineHeight, max, tagED::maxPixelWidth, min, MLBuildchLines(), MLDrawText(), MLEnsureCaretVisible(), MLIchToLine(), MLIchToXYPos(), MLIchToYPos(), MLUndo(), MLUpdateiCaretLine(), NotifyWinEvent(), NtUserInvalidateRect(), NtUserMessageBeep, tagED::pLpkEditCallout, Pundo, tagED::pwnd, tagED::rcFmt, TRUE, tagED::wLeftMargin, tagED::wMaxNegAcharPos, tagED::wRightMargin, and tagED::xOffset.

Referenced by ECImeComposition(), MLChar(), MLPasteText(), MLReplaceSel(), and MLUndo().

01045 { 01046 HDC hdc; 01047 ICH validCch = cchInsert; 01048 ICH oldCaret = ped->ichCaret; 01049 int oldCaretLine = ped->iCaretLine; 01050 BOOL fCRLF = FALSE; 01051 LONG ll, hl; 01052 POINT xyPosInitial; 01053 POINT xyPosFinal; 01054 HWND hwndSave = ped->hwnd; 01055 UNDO undo; 01056 ICH validCchTemp; 01057 01058 xyPosInitial.x=0; 01059 xyPosInitial.y=0; 01060 xyPosFinal.x=0; 01061 xyPosFinal.y=0; 01062 01063 if (validCch == 0) 01064 return 0; 01065 01066 if (ped->cchTextMax <= ped->cch) { 01067 01068 /* 01069 * When the max chars is reached already, notify parent 01070 * Fix for Bug #4183 -- 02/06/91 -- SANKAR -- 01071 */ 01072 ECNotifyParent(ped,EN_MAXTEXT); 01073 return 0; 01074 } 01075 01076 /* 01077 * Limit the amount of text we add 01078 */ 01079 validCch = min(validCch, ped->cchTextMax - ped->cch); 01080 01081 /* 01082 * Make sure we don't split a CRLF in half 01083 */ 01084 if (validCch) { 01085 if (ped->fAnsi) { 01086 if (*(WORD UNALIGNED *)(lpText + validCch - 1) == 0x0A0D) 01087 validCch--; 01088 } else { 01089 if (*(DWORD UNALIGNED *)(lpText + (validCch - 1) * ped->cbChar) == 0x000A000D) 01090 validCch--; 01091 } 01092 } 01093 if (!validCch) { 01094 /* 01095 * When the max chars is reached already, notify parent 01096 * Fix for Bug #4183 -- 02/06/91 -- SANKAR -- 01097 */ 01098 ECNotifyParent(ped,EN_MAXTEXT); 01099 return 0; 01100 } 01101 01102 if (validCch == 2) { 01103 if (ped->fAnsi) { 01104 if (*(WORD UNALIGNED *)lpText == 0x0A0D) 01105 fCRLF = TRUE; 01106 } else { 01107 if (*(DWORD UNALIGNED *)lpText == 0x000A000D) 01108 fCRLF = TRUE; 01109 } 01110 } 01111 01112 // 01113 // Save current undo state always, but clear it out only if !AutoVScroll 01114 // 01115 ECSaveUndo(Pundo(ped), (PUNDO)&undo, !ped->fAutoVScroll); 01116 01117 hdc = ECGetEditDC(ped, FALSE); 01118 /* 01119 * We only need the y position. Since with an LPK loaded 01120 * calculating the x position is an intensive job, just 01121 * call MLIchToYPos. 01122 */ 01123 if (ped->cch) 01124 if (ped->pLpkEditCallout) 01125 xyPosInitial.y = MLIchToYPos(ped, ped->cch-1, FALSE); 01126 else 01127 MLIchToXYPos(ped, hdc, ped->cch - 1, FALSE, &xyPosInitial); 01128 01129 /* 01130 * Insert the text 01131 */ 01132 validCchTemp = validCch; // may not be needed, but just for precautions.. 01133 if (!ECInsertText(ped, lpText, &validCchTemp)) { 01134 01135 // Restore previous undo buffer if it was cleared 01136 if (!ped->fAutoVScroll) 01137 ECSaveUndo((PUNDO)&undo, Pundo(ped), FALSE); 01138 01139 ECReleaseEditDC(ped, hdc, FALSE); 01140 ECNotifyParent(ped, EN_ERRSPACE); 01141 return (0); 01142 } 01143 01144 #if DBG 01145 if (validCch != validCchTemp) { 01146 /* 01147 * All characters in lpText has not been inserted to ped. 01148 * This could happen when cch is close to cchMax. 01149 * Better revisit this after NT5 ships. 01150 */ 01151 RIPMSG2(RIP_WARNING, "MLInsertText: validCch is changed (%x -> %x) in ECInsertText.", 01152 validCch, validCchTemp); 01153 } 01154 #endif 01155 01156 /* 01157 * Note that ped->ichCaret is updated by ECInsertText 01158 */ 01159 MLBuildchLines(ped, (ICH)oldCaretLine, (int)validCch, fCRLF?(BOOL)FALSE:fUserTyping, &ll, &hl); 01160 01161 if (ped->cch) 01162 /* 01163 * We only need the y position. Since with an LPK loaded 01164 * calculating the x position is an intensive job, just 01165 * call MLIchToYPos. 01166 */ 01167 if (ped->pLpkEditCallout) 01168 xyPosFinal.y = MLIchToYPos(ped, ped->cch-1, FALSE); 01169 else 01170 MLIchToXYPos(ped, hdc, ped->cch - 1, FALSE,&xyPosFinal); 01171 01172 if (xyPosFinal.y < xyPosInitial.y && ((ICH)ped->ichScreenStart) + ped->ichLinesOnScreen >= ped->cLines - 1) { 01173 RECT rc; 01174 01175 CopyRect((LPRECT)&rc, (LPRECT)&ped->rcFmt); 01176 rc.top = xyPosFinal.y + ped->lineHeight; 01177 if (ped->pLpkEditCallout) { 01178 int xFarOffset = ped->xOffset + ped->rcFmt.right - ped->rcFmt.left; 01179 // Include left or right margins in display unless clipped 01180 // by horizontal scrolling. 01181 if (ped->wLeftMargin) { 01182 if (!( ped->format == ES_LEFT // Only ES_LEFT (Nearside alignment) can get clipped 01183 && ( (!ped->fRtoLReading && ped->xOffset > 0) // LTR and first char not fully in view 01184 || ( ped->fRtoLReading && xFarOffset < ped->maxPixelWidth)))) { //RTL and last char not fully in view 01185 rc.left -= ped->wLeftMargin; 01186 } 01187 } 01188 01189 // Process right margin 01190 if (ped->wRightMargin) { 01191 if (!( ped->format == ES_LEFT // Only ES_LEFT (Nearside alignment) can get clipped 01192 && ( ( ped->fRtoLReading && ped->xOffset > 0) // RTL and first char not fully in view 01193 || (!ped->fRtoLReading && xFarOffset < ped->maxPixelWidth)))) { // LTR and last char not fully in view 01194 rc.right += ped->wRightMargin; 01195 } 01196 } 01197 } 01198 NtUserInvalidateRect(ped->hwnd, (LPRECT)&rc, TRUE); 01199 } 01200 01201 if (!ped->fAutoVScroll) { 01202 if (ped->ichLinesOnScreen < ped->cLines) { 01203 MLUndo(ped); 01204 ECEmptyUndo(Pundo(ped)); 01205 01206 ECSaveUndo(&undo, Pundo(ped), FALSE); 01207 01208 NtUserMessageBeep(0); 01209 ECReleaseEditDC(ped, hdc, FALSE); 01210 01211 /* 01212 * When the max lines is reached already, notify parent 01213 * Fix for Bug #7586 -- 10/14/91 -- SANKAR -- 01214 */ 01215 ECNotifyParent(ped,EN_MAXTEXT); 01216 return (0); 01217 } else { 01218 ECEmptyUndo(&undo); 01219 } 01220 } 01221 01222 if (fUserTyping && ped->fWrap) { 01223 // 01224 // To avoid oldCaret points intermediate of DBCS character, 01225 // adjust oldCaret position if necessary. 01226 // 01227 // !!!CR If MLBuildchLines() returns reasonable value ( and I think 01228 // it does), we don't probably need this. Check this out later. 01229 // 01230 if (ped->fDBCS && ped->fAnsi) { 01231 oldCaret = ECAdjustIch(ped, 01232 ECLock(ped), 01233 min((ICH)LOWORD(ll),oldCaret)); 01234 /* ECUnlock(ped); */ 01235 } else { // same as original code 01236 oldCaret = min((ICH)LOWORD(ll), oldCaret); 01237 } 01238 } 01239 01240 // Update ped->iCaretLine properly. 01241 MLUpdateiCaretLine(ped); 01242 01243 ECNotifyParent(ped, EN_UPDATE); 01244 01245 /* 01246 * Make sure window still exists. 01247 */ 01248 if (!IsWindow(hwndSave)) 01249 return 0; 01250 01251 if (_IsWindowVisible(ped->pwnd)) { 01252 01253 // 01254 // If the current font has negative A widths, we may have to start 01255 // drawing a few characters before the oldCaret position. 01256 // 01257 if (ped->wMaxNegAcharPos) { 01258 int iLine = MLIchToLine(ped, oldCaret); 01259 oldCaret = max( ((int)(oldCaret - ped->wMaxNegAcharPos)), 01260 ((int)(ped->chLines[iLine]))); 01261 } 01262 01263 // Redraw to end of screen/text if CRLF or large insert 01264 if (fCRLF || !fUserTyping) { 01265 01266 /* 01267 * Redraw to end of screen/text if crlf or large insert. 01268 */ 01269 MLDrawText(ped, hdc, (fUserTyping ? oldCaret : 0), ped->cch, FALSE); 01270 } else 01271 MLDrawText(ped, hdc, oldCaret, max(ped->ichCaret, (ICH)hl), FALSE); 01272 } 01273 01274 ECReleaseEditDC(ped, hdc, FALSE); 01275 01276 /* 01277 * Make sure we can see the cursor 01278 */ 01279 MLEnsureCaretVisible(ped); 01280 01281 ped->fDirty = TRUE; 01282 01283 ECNotifyParent(ped, EN_CHANGE); 01284 01285 if (validCch < cchInsert) 01286 ECNotifyParent(ped, EN_MAXTEXT); 01287 01288 if (validCch && FWINABLE()) { 01289 NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, ped->hwnd, OBJID_CLIENT, INDEXID_CONTAINER); 01290 } 01291 01292 /* 01293 * Make sure the window still exists. 01294 */ 01295 if (!IsWindow(hwndSave)) 01296 return 0; 01297 else 01298 return validCch; 01299 }

void MLKeyDown PED  ped,
UINT  virtKeyCode,
int  keyMods
 

Definition at line 2028 of file editml.c.

References tagED::aveCharWidth, BOOL, tagED::cbChar, tagED::cch, tagED::chLines, tagED::cLines, CTRLDOWN, DWORD, ECGetEditDC(), ECGetModKeys(), ECLock(), ECReleaseEditDC(), ECUnlock(), ECWord(), EFWANTRETURN, FALSE, tagED::fAnsi, tagED::fFocus, tagED::fInDialogBox, tagED::fMouseDown, tagED::fReadOnly, tagED::fWrap, GETAPPVER, GetDlgItem(), HanjaKeyHandler(), tagED::hwnd, tagED::hwndParent, tagED::iCaretLine, ICH, tagED::ichCaret, tagED::ichMaxSel, tagED::ichMinSel, L, tagED::lineHeight, MLChangeSelection(), MLChar(), MLEnsureCaretVisible(), MLIchToLine(), MLIchToXYPos(), MLLine(), MLMouseMotion(), MLMoveSelection(), MLMoveSelectionRestricted(), MLSetCaretPosition(), NONEDOWN, NULL, tagED::pLpkEditCallout, PostMessage(), tagED::pwnd, tagED::rcFmt, SendMessage(), SendMessageWorker(), SHFTDOWN, TestWF, TRUE, UINT, and VER40.

Referenced by MLEditWndProc().

02032 { 02033 HDC hdc; 02034 BOOL prevLine; 02035 POINT mousePt; 02036 int defaultDlgId; 02037 int iScrollAmt; 02038 02039 /* 02040 * Variables we will use for redrawing the updated text 02041 */ 02042 02043 /* 02044 * new selection is specified by newMinSel, newMaxSel 02045 */ 02046 ICH newMaxSel = ped->ichMaxSel; 02047 ICH newMinSel = ped->ichMinSel; 02048 02049 /* 02050 * Flags for drawing the updated text 02051 */ 02052 BOOL changeSelection = FALSE; 02053 02054 /* 02055 * Comparisons we do often 02056 */ 02057 BOOL MinEqMax = (newMaxSel == newMinSel); 02058 BOOL MinEqCar = (ped->ichCaret == newMinSel); 02059 BOOL MaxEqCar = (ped->ichCaret == newMaxSel); 02060 02061 /* 02062 * State of shift and control keys. 02063 */ 02064 int scState; 02065 02066 if (ped->fMouseDown) { 02067 02068 /* 02069 * If we are in the middle of a mousedown command, don't do anything. 02070 */ 02071 return ; 02072 } 02073 02074 scState = ECGetModKeys(keyMods); 02075 02076 switch (virtKeyCode) { 02077 case VK_ESCAPE: 02078 if (ped->fInDialogBox) { 02079 02080 /* 02081 * This condition is removed because, if the dialogbox does not 02082 * have a CANCEL button and if ESC is hit when focus is on a 02083 * ML edit control the dialogbox must close whether it has cancel 02084 * button or not to be consistent with SL edit control; 02085 * DefDlgProc takes care of the disabled CANCEL button case. 02086 * Fix for Bug #4123 -- 02/07/91 -- SANKAR -- 02087 */ 02088 #if 0 02089 if (GetDlgItem(ped->hwndParent, IDCANCEL)) 02090 #endif 02091 02092 /* 02093 * User hit ESC...Send a close message (which in turn sends a 02094 * cancelID to the app in DefDialogProc... 02095 */ 02096 PostMessage(ped->hwndParent, WM_CLOSE, 0, 0L); 02097 } 02098 return ; 02099 02100 case VK_RETURN: 02101 if (ped->fInDialogBox) { 02102 02103 /* 02104 * If this multiline edit control is in a dialog box, then we want 02105 * the RETURN key to be sent to the default dialog button (if there 02106 * is one). CTRL-RETURN will insert a RETURN into the text. Note 02107 * that CTRL-RETURN automatically translates into a linefeed (0x0A) 02108 * and in the MLCharHandler, we handle this as if a return was 02109 * entered. 02110 */ 02111 if (scState != CTRLDOWN) { 02112 02113 if (TestWF(ped->pwnd, EFWANTRETURN)) { 02114 02115 /* 02116 * This edit control wants cr to be inserted so break out of 02117 * case. 02118 */ 02119 return ; 02120 } 02121 02122 defaultDlgId = (int)(DWORD)LOWORD(SendMessage(ped->hwndParent, 02123 DM_GETDEFID, 0, 0L)); 02124 if (defaultDlgId) { 02125 HWND hwnd = GetDlgItem(ped->hwndParent, defaultDlgId); 02126 if (hwnd) { 02127 SendMessage(ped->hwndParent, WM_NEXTDLGCTL, (WPARAM)hwnd, 1L); 02128 if (!ped->fFocus) 02129 PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0L); 02130 } 02131 } 02132 } 02133 02134 return ; 02135 } 02136 break; 02137 02138 case VK_TAB: 02139 02140 /* 02141 * If this multiline edit control is in a dialog box, then we want the 02142 * TAB key to take you to the next control, shift TAB to take you to the 02143 * previous control. We always want CTRL-TAB to insert a tab into the 02144 * edit control regardless of weather or not we're in a dialog box. 02145 */ 02146 if (scState == CTRLDOWN) 02147 MLChar(ped, virtKeyCode, keyMods); 02148 else if (ped->fInDialogBox) 02149 SendMessage(ped->hwndParent, WM_NEXTDLGCTL, scState == SHFTDOWN, 0L); 02150 02151 return ; 02152 02153 case VK_LEFT: 02154 // 02155 // If the caret isn't at the beginning, we can move left 02156 // 02157 if (ped->ichCaret) { 02158 // Get new caret pos. 02159 if (scState & CTRLDOWN) { 02160 // Move caret word left 02161 ECWord(ped, ped->ichCaret, TRUE, &ped->ichCaret, NULL); 02162 } else { 02163 if (ped->pLpkEditCallout) { 02164 ped->ichCaret = MLMoveSelectionRestricted(ped, ped->ichCaret, TRUE); 02165 } else { 02166 // Move caret char left 02167 ped->ichCaret = MLMoveSelection(ped, ped->ichCaret, TRUE); 02168 } 02169 } 02170 02171 // Get new selection 02172 if (scState & SHFTDOWN) { 02173 if (MaxEqCar && !MinEqMax) { 02174 // Reduce selection 02175 newMaxSel = ped->ichCaret; 02176 02177 UserAssert(newMinSel == ped->ichMinSel); 02178 } else { 02179 // Extend selection 02180 newMinSel = ped->ichCaret; 02181 } 02182 } else { 02183 // Clear selection 02184 newMaxSel = newMinSel = ped->ichCaret; 02185 } 02186 02187 changeSelection = TRUE; 02188 } else { 02189 // 02190 // If the user tries to move left and we are at the 0th 02191 // character and there is a selection, then cancel the 02192 // selection. 02193 // 02194 if ( (ped->ichMaxSel != ped->ichMinSel) && 02195 !(scState & SHFTDOWN) ) { 02196 changeSelection = TRUE; 02197 newMaxSel = newMinSel = ped->ichCaret; 02198 } 02199 } 02200 break; 02201 02202 case VK_RIGHT: 02203 // 02204 // If the caret isn't at the end, we can move right. 02205 // 02206 if (ped->ichCaret < ped->cch) { 02207 // 02208 // Get new caret pos. 02209 // 02210 if (scState & CTRLDOWN) { 02211 // Move caret word right 02212 ECWord(ped, ped->ichCaret, FALSE, NULL, &ped->ichCaret); 02213 } else { 02214 // Move caret char right 02215 if (ped->pLpkEditCallout) { 02216 ped->ichCaret = MLMoveSelectionRestricted(ped, ped->ichCaret, FALSE); 02217 } else { 02218 ped->ichCaret = MLMoveSelection(ped, ped->ichCaret, FALSE); 02219 } 02220 } 02221 02222 // 02223 // Get new selection. 02224 // 02225 if (scState & SHFTDOWN) { 02226 if (MinEqCar && !MinEqMax) { 02227 // Reduce selection 02228 newMinSel = ped->ichCaret; 02229 02230 UserAssert(newMaxSel == ped->ichMaxSel); 02231 } else { 02232 // Extend selection 02233 newMaxSel = ped->ichCaret; 02234 } 02235 } else { 02236 // Clear selection 02237 newMaxSel = newMinSel = ped->ichCaret; 02238 } 02239 02240 changeSelection = TRUE; 02241 } else { 02242 // 02243 // If the user tries to move right and we are at the last 02244 // character and there is a selection, then cancel the 02245 // selection. 02246 // 02247 if ( (ped->ichMaxSel != ped->ichMinSel) && 02248 !(scState & SHFTDOWN) ) { 02249 newMaxSel = newMinSel = ped->ichCaret; 02250 changeSelection = TRUE; 02251 } 02252 } 02253 break; 02254 02255 case VK_UP: 02256 case VK_DOWN: 02257 if (ped->cLines - 1 != ped->iCaretLine && 02258 ped->ichCaret == ped->chLines[ped->iCaretLine + 1]) 02259 prevLine = TRUE; 02260 else 02261 prevLine = FALSE; 02262 02263 hdc = ECGetEditDC(ped, TRUE); 02264 MLIchToXYPos(ped, hdc, ped->ichCaret, prevLine, &mousePt); 02265 ECReleaseEditDC(ped, hdc, TRUE); 02266 mousePt.y += 1 + (virtKeyCode == VK_UP ? -ped->lineHeight : ped->lineHeight); 02267 02268 if (!(scState & CTRLDOWN)) { 02269 // 02270 // Send fake mouse messages to handle this 02271 // If VK_SHIFT is down, extend selection & move caret up/down 02272 // 1 line. Otherwise, clear selection & move caret. 02273 // 02274 MLMouseMotion(ped, WM_LBUTTONDOWN, 02275 !(scState & SHFTDOWN) ? 0 : MK_SHIFT, &mousePt); 02276 MLMouseMotion(ped, WM_LBUTTONUP, 02277 !(scState & SHFTDOWN) ? 0 : MK_SHIFT, &mousePt); 02278 } 02279 break; 02280 02281 case VK_HOME: 02282 // 02283 // Update caret. 02284 // 02285 if (scState & CTRLDOWN) { 02286 // Move caret to beginning of text. 02287 ped->ichCaret = 0; 02288 } else { 02289 // Move caret to beginning of line. 02290 ped->ichCaret = ped->chLines[ped->iCaretLine]; 02291 } 02292 02293 // 02294 // Update selection. 02295 // 02296 newMinSel = ped->ichCaret; 02297 02298 if (scState & SHFTDOWN) { 02299 if (MaxEqCar && !MinEqMax) { 02300 if (scState & CTRLDOWN) 02301 newMaxSel = ped->ichMinSel; 02302 else { 02303 newMinSel = ped->ichMinSel; 02304 newMaxSel = ped->ichCaret; 02305 } 02306 } 02307 } else { 02308 // Clear selection 02309 newMaxSel = ped->ichCaret; 02310 } 02311 02312 changeSelection = TRUE; 02313 break; 02314 02315 case VK_END: 02316 // 02317 // Update caret. 02318 // 02319 if (scState & CTRLDOWN) { 02320 // Move caret to end of text. 02321 ped->ichCaret = ped->cch; 02322 } else { 02323 // Move caret to end of line. 02324 ped->ichCaret = ped->chLines[ped->iCaretLine] + 02325 MLLine(ped, ped->iCaretLine); 02326 } 02327 02328 // Update selection. 02329 newMaxSel = ped->ichCaret; 02330 02331 if (scState & SHFTDOWN) { 02332 if (MinEqCar && !MinEqMax) { 02333 // Reduce selection 02334 if (scState & CTRLDOWN) { 02335 newMinSel = ped->ichMaxSel; 02336 } else { 02337 newMinSel = ped->ichCaret; 02338 newMaxSel = ped->ichMaxSel; 02339 } 02340 } 02341 } else { 02342 // Clear selection 02343 newMinSel = ped->ichCaret; 02344 } 02345 02346 changeSelection = TRUE; 02347 break; 02348 02349 // FE_IME // EC_INSERT_COMPOSITION_CHAR : MLKeyDown() : VK_HANJA support 02350 case VK_HANJA: 02351 if ( HanjaKeyHandler( ped ) ) { 02352 changeSelection = TRUE; 02353 newMinSel = ped->ichCaret; 02354 newMaxSel = ped->ichCaret + (ped->fAnsi ? 2 : 1); 02355 } 02356 break; 02357 02358 case VK_PRIOR: 02359 case VK_NEXT: 02360 if (!(scState & CTRLDOWN)) { 02361 /* 02362 * Vertical scroll by one visual screen 02363 */ 02364 hdc = ECGetEditDC(ped, TRUE); 02365 MLIchToXYPos(ped, hdc, ped->ichCaret, FALSE, &mousePt); 02366 ECReleaseEditDC(ped, hdc, TRUE); 02367 mousePt.y += 1; 02368 02369 SendMessage(ped->hwnd, WM_VSCROLL, virtKeyCode == VK_PRIOR ? SB_PAGEUP : SB_PAGEDOWN, 0L); 02370 02371 /* 02372 * Move the cursor there 02373 */ 02374 MLMouseMotion(ped, WM_LBUTTONDOWN, !(scState & SHFTDOWN) ? 0 : MK_SHIFT, &mousePt); 02375 MLMouseMotion(ped, WM_LBUTTONUP, !(scState & SHFTDOWN) ? 0 : MK_SHIFT, &mousePt); 02376 02377 } else { 02378 /* 02379 * Horizontal scroll by one screenful minus one char 02380 */ 02381 iScrollAmt = ((ped->rcFmt.right - ped->rcFmt.left) / ped->aveCharWidth) - 1; 02382 if (virtKeyCode == VK_PRIOR) 02383 iScrollAmt *= -1; /* For previous page */ 02384 02385 SendMessage(ped->hwnd, WM_HSCROLL, MAKELONG(EM_LINESCROLL, iScrollAmt), 0); 02386 break; 02387 } 02388 break; 02389 02390 case VK_DELETE: 02391 if (ped->fReadOnly) 02392 break; 02393 02394 switch (scState) { 02395 case NONEDOWN: 02396 02397 /* 02398 * Clear selection. If no selection, delete (clear) character 02399 * right 02400 */ 02401 if ((ped->ichMaxSel < ped->cch) && (ped->ichMinSel == ped->ichMaxSel)) { 02402 02403 /* 02404 * Move cursor forwards and send a backspace message... 02405 */ 02406 if (ped->pLpkEditCallout) { 02407 ped->ichMinSel = ped->ichCaret; 02408 ped->ichMaxSel = MLMoveSelectionRestricted(ped, ped->ichCaret, FALSE); 02409 } else { 02410 ped->ichCaret = MLMoveSelection(ped, ped->ichCaret, FALSE); 02411 ped->ichMaxSel = ped->ichMinSel = ped->ichCaret; 02412 } 02413 02414 goto DeleteAnotherChar; 02415 } 02416 break; 02417 02418 case SHFTDOWN: 02419 02420 /* 02421 * CUT selection ie. remove and copy to clipboard, or if no 02422 * selection, delete (clear) character left. 02423 */ 02424 if (ped->ichMinSel == ped->ichMaxSel) { 02425 goto DeleteAnotherChar; 02426 } else { 02427 SendMessage(ped->hwnd, WM_CUT, (UINT)0, 0L); 02428 } 02429 02430 break; 02431 02432 case CTRLDOWN: 02433 02434 /* 02435 * Clear selection, or delete to end of line if no selection 02436 */ 02437 if ((ped->ichMaxSel < ped->cch) && (ped->ichMinSel == ped->ichMaxSel)) { 02438 ped->ichMaxSel = ped->ichCaret = ped->chLines[ped->iCaretLine] + 02439 MLLine(ped, ped->iCaretLine); 02440 } 02441 break; 02442 } 02443 02444 if (!(scState & SHFTDOWN) && (ped->ichMinSel != ped->ichMaxSel)) { 02445 02446 DeleteAnotherChar: 02447 if (GETAPPVER() >= VER40) { 02448 MLChar(ped, VK_BACK, 0); 02449 } else { 02450 SendMessageWorker(ped->pwnd, WM_CHAR, VK_BACK, 0, ped->fAnsi); 02451 } 02452 } 02453 02454 /* 02455 * No need to update text or selection since BACKSPACE message does it 02456 * for us. 02457 */ 02458 break; 02459 02460 case VK_INSERT: 02461 if (scState == CTRLDOWN || scState == SHFTDOWN) { 02462 02463 /* 02464 * if CTRLDOWN Copy current selection to clipboard 02465 */ 02466 02467 /* 02468 * if SHFTDOWN Paste clipboard 02469 */ 02470 SendMessage(ped->hwnd, (UINT)(scState == CTRLDOWN ? WM_COPY : WM_PASTE), 0, 0); 02471 } 02472 break; 02473 } 02474 02475 if (changeSelection) { 02476 hdc = ECGetEditDC(ped, FALSE); 02477 MLChangeSelection(ped, hdc, newMinSel, newMaxSel); 02478 02479 /* 02480 * Set the caret's line 02481 */ 02482 ped->iCaretLine = MLIchToLine(ped, ped->ichCaret); 02483 02484 if (virtKeyCode == VK_END && 02485 // Next line: Win95 Bug#11822, EditControl repaint (Sankar) 02486 (ped->ichCaret == ped->chLines[ped->iCaretLine]) && 02487 ped->ichCaret < ped->cch && 02488 ped->fWrap && ped->iCaretLine > 0) { 02489 LPSTR pText = ECLock(ped); 02490 02491 /* 02492 * Handle moving to the end of a word wrapped line. This keeps the 02493 * cursor from falling to the start of the next line if we have word 02494 * wrapped and there is no CRLF. 02495 */ 02496 if ( ped->fAnsi ) { 02497 if (*(WORD UNALIGNED *)(pText + 02498 ped->chLines[ped->iCaretLine] - 2) != 0x0A0D) { 02499 ped->iCaretLine--; 02500 } 02501 } else { 02502 if (*(DWORD UNALIGNED *)(pText + 02503 (ped->chLines[ped->iCaretLine] - 2)*ped->cbChar) != 0x000A000D) { 02504 ped->iCaretLine--; 02505 } 02506 } 02507 ECUnlock(ped); 02508 } 02509 02510 /* 02511 * Since drawtext sets the caret position 02512 */ 02513 MLSetCaretPosition(ped, hdc); 02514 ECReleaseEditDC(ped, hdc, FALSE); 02515 02516 /* 02517 * Make sure we can see the cursor 02518 */ 02519 MLEnsureCaretVisible(ped); 02520 } 02521 }

void MLKillFocus PED  ped  ) 
 

Definition at line 3329 of file editml.c.

References _IsWindowVisible(), ECGetEditDC(), ECNotifyParent(), ECReleaseEditDC(), FALSE, tagED::fFocus, tagED::fNoHideSel, gcWheelDelta, tagED::ichMaxSel, tagED::ichMinSel, MLDrawText(), NtUserDestroyCaret, tagED::pwnd, and TRUE.

Referenced by MLEditWndProc().

03331 { 03332 HDC hdc; 03333 03334 /* 03335 * Reset the wheel delta count. 03336 */ 03337 gcWheelDelta = 0; 03338 03339 if (ped->fFocus) { 03340 ped->fFocus = 0; /* Clear focus */ 03341 03342 /* 03343 * Do this only if we still have the focus. But we always notify the 03344 * parent that we lost the focus whether or not we originally had the 03345 * focus. 03346 */ 03347 03348 /* 03349 * Hide the current selection if needed 03350 */ 03351 if (!ped->fNoHideSel && ped->ichMinSel != ped->ichMaxSel && 03352 _IsWindowVisible(ped->pwnd)) { 03353 hdc = ECGetEditDC(ped, FALSE); 03354 MLDrawText(ped, hdc, ped->ichMinSel, ped->ichMaxSel, TRUE); 03355 ECReleaseEditDC(ped, hdc, FALSE); 03356 } 03357 03358 /* 03359 * Destroy the caret 03360 */ 03361 NtUserDestroyCaret(); 03362 } 03363 03364 /* 03365 * Notify parent that we lost the focus. 03366 */ 03367 ECNotifyParent(ped, EN_KILLFOCUS); 03368 }

ICH MLLine PED  ped,
ICH  lineNumber
 

Definition at line 374 of file editml.c.

References tagED::cch, tagED::chLines, tagED::cLines, DWORD, ECLock(), ECUnlock(), tagED::fAnsi, and ICH.

Referenced by MLCalcXOffset(), MLDrawText(), MLGetLine(), MLIchToXYPos(), MLKeyDown(), MLLineLength(), and MLMouseToIch().

00377 { 00378 ICH result; 00379 00380 UserAssert(lineNumber < ped->cLines); 00381 00382 if (lineNumber >= ped->cLines) 00383 return (0); 00384 00385 if (lineNumber == ped->cLines - 1) { 00386 00387 /* 00388 * Since we can't have a CRLF on the last line 00389 */ 00390 return (ped->cch - ped->chLines[ped->cLines - 1]); 00391 } else { 00392 result = ped->chLines[lineNumber + 1] - ped->chLines[lineNumber]; 00393 RIPMSG1(RIP_VERBOSE, "MLLine result=%d\n", result); 00394 00395 /* 00396 * Now check for CRLF or CRCRLF at end of line 00397 */ 00398 if (result > 1) { 00399 if (ped->fAnsi) { 00400 LPSTR pText; 00401 00402 pText = ECLock(ped) + ped->chLines[lineNumber + 1] - 2; 00403 if (*(WORD UNALIGNED *)pText == 0x0A0D) { 00404 result -= 2; 00405 if (result && *(--pText) == 0x0D) 00406 /* 00407 * In case there was a CRCRLF 00408 */ 00409 result--; 00410 } 00411 } else { // !fAnsi 00412 LPWSTR pwText; 00413 00414 pwText = (LPWSTR)ECLock(ped) + 00415 (ped->chLines[lineNumber + 1] - 2); 00416 if (*(DWORD UNALIGNED *)pwText == 0x000A000D) { 00417 result = result - 2; 00418 if (result && *(--pwText) == 0x0D) 00419 /* 00420 * In case there was a CRCRLF 00421 */ 00422 result--; 00423 } 00424 00425 } 00426 ECUnlock(ped); 00427 } 00428 } 00429 return (result); 00430 }

void MLMouseMotion PED  ped,
UINT  message,
UINT  virtKeyDown,
LPPOINT  mousePt
 

Definition at line 2792 of file editml.c.

References BOOL, tagED::chLines, ECGetEditDC(), ECIsDBCSLeadByte(), ECLock(), ECReleaseEditDC(), ECUnlock(), ECWord(), FALSE, tagED::fAnsi, tagED::fDBCS, tagED::fFocus, tagED::fMouseDown, gpsi, tagED::hwnd, tagED::iCaretLine, ICH, tagED::ichCaret, tagED::ichMaxSel, tagED::ichMinSel, tagED::ichStartMaxSel, tagED::ichStartMinSel, IDSYS_SCROLL, MLChangeSelection(), MLEnsureCaretVisible(), MLMouseToIch(), MLSetCaretPosition(), NtUserKillSystemTimer, NtUserReleaseCapture, NtUserSetCapture(), NtUserSetFocus(), NtUserSetSystemTimer(), NULL, tagED::prevKeys, tagED::ptPrevMouse, tagED::rcFmt, TRUE, and UINT.

Referenced by MLEditWndProc(), and MLKeyDown().

02797 { 02798 BOOL fChangedSel = FALSE; 02799 02800 HDC hdc = ECGetEditDC(ped, TRUE); 02801 02802 ICH ichMaxSel = ped->ichMaxSel; 02803 ICH ichMinSel = ped->ichMinSel; 02804 02805 ICH mouseCch; 02806 ICH mouseLine; 02807 int i, j; 02808 LONG ll, lh; 02809 02810 mouseCch = MLMouseToIch(ped, hdc, mousePt, &mouseLine); 02811 02812 /* 02813 * Save for timer 02814 */ 02815 ped->ptPrevMouse = *mousePt; 02816 ped->prevKeys = virtKeyDown; 02817 02818 switch (message) { 02819 case WM_LBUTTONDBLCLK: 02820 /* 02821 * if shift key is down, extend selection to word we double clicked on 02822 * else clear current selection and select word. 02823 */ 02824 // LiZ -- 5/5/93 02825 if (ped->fAnsi && ped->fDBCS) { 02826 LPSTR pText = ECLock(ped); 02827 ECWord(ped,ped->ichCaret, 02828 ECIsDBCSLeadByte(ped, *(pText+(ped->ichCaret))) 02829 ? FALSE : 02830 (ped->ichCaret == ped->chLines[ped->iCaretLine] 02831 ? FALSE : TRUE), &ll, &lh); 02832 ECUnlock(ped); 02833 } else { 02834 ECWord(ped, mouseCch, !(mouseCch == ped->chLines[mouseLine]), &ll, &lh); 02835 } 02836 if (!(virtKeyDown & MK_SHIFT)) { 02837 // If shift key isn't down, move caret to mouse point and clear 02838 // old selection 02839 ichMinSel = ll; 02840 ichMaxSel = ped->ichCaret = lh; 02841 } else { 02842 // Shiftkey is down so we want to maintain the current selection 02843 // (if any) and just extend or reduce it 02844 if (ped->ichMinSel == ped->ichCaret) { 02845 ichMinSel = ped->ichCaret = ll; 02846 ECWord(ped, ichMaxSel, TRUE, &ll, &lh); 02847 } else { 02848 ichMaxSel = ped->ichCaret = lh; 02849 ECWord(ped, ichMinSel, FALSE, &ll, &lh); 02850 } 02851 } 02852 02853 ped->ichStartMinSel = ll; 02854 ped->ichStartMaxSel = lh; 02855 02856 goto InitDragSelect; 02857 02858 case WM_MOUSEMOVE: 02859 if (ped->fMouseDown) { 02860 02861 /* 02862 * Set the system timer to automatically scroll when mouse is 02863 * outside of the client rectangle. Speed of scroll depends on 02864 * distance from window. 02865 */ 02866 i = mousePt->y < 0 ? -mousePt->y : mousePt->y - ped->rcFmt.bottom; 02867 j = gpsi->dtScroll - ((UINT)i << 4); 02868 if (j < 1) 02869 j = 1; 02870 NtUserSetSystemTimer(ped->hwnd, IDSYS_SCROLL, (UINT)j, NULL); 02871 02872 fChangedSel = TRUE; 02873 02874 // Extend selection, move caret right 02875 if (ped->ichStartMinSel || ped->ichStartMaxSel) { 02876 // We're in WORD SELECT mode 02877 BOOL fReverse = (mouseCch <= ped->ichStartMinSel); 02878 ECWord(ped, mouseCch, !fReverse, &ll, &lh); 02879 if (fReverse) { 02880 ichMinSel = ped->ichCaret = ll; 02881 ichMaxSel = ped->ichStartMaxSel; 02882 } else { 02883 ichMinSel = ped->ichStartMinSel; 02884 ichMaxSel = ped->ichCaret = lh; 02885 } 02886 } else if ((ped->ichMinSel == ped->ichCaret) && 02887 (ped->ichMinSel != ped->ichMaxSel)) 02888 // Reduce selection extent 02889 ichMinSel = ped->ichCaret = mouseCch; 02890 else 02891 // Extend selection extent 02892 ichMaxSel = ped->ichCaret = mouseCch; 02893 02894 ped->iCaretLine = mouseLine; 02895 } 02896 break; 02897 02898 case WM_LBUTTONDOWN: 02899 ll = lh = mouseCch; 02900 02901 if (!(virtKeyDown & MK_SHIFT)) { 02902 // If shift key isn't down, move caret to mouse point and clear 02903 // old selection 02904 ichMinSel = ichMaxSel = ped->ichCaret = mouseCch; 02905 } else { 02906 // Shiftkey is down so we want to maintain the current selection 02907 // (if any) and just extend or reduce it 02908 if (ped->ichMinSel == ped->ichCaret) 02909 ichMinSel = ped->ichCaret = mouseCch; 02910 else 02911 ichMaxSel = ped->ichCaret = mouseCch; 02912 } 02913 02914 ped->ichStartMinSel = ped->ichStartMaxSel = 0; 02915 02916 InitDragSelect: 02917 ped->iCaretLine = mouseLine; 02918 02919 ped->fMouseDown = FALSE; 02920 NtUserSetCapture(ped->hwnd); 02921 ped->fMouseDown = TRUE; 02922 fChangedSel = TRUE; 02923 02924 // Set the timer so that we can scroll automatically when the mouse 02925 // is moved outside the window rectangle. 02926 NtUserSetSystemTimer(ped->hwnd, IDSYS_SCROLL, gpsi->dtScroll, NULL); 02927 break; 02928 02929 case WM_LBUTTONUP: 02930 if (ped->fMouseDown) { 02931 02932 /* 02933 * Kill the timer so that we don't do auto mouse moves anymore 02934 */ 02935 NtUserKillSystemTimer(ped->hwnd, IDSYS_SCROLL); 02936 NtUserReleaseCapture(); 02937 MLSetCaretPosition(ped, hdc); 02938 ped->fMouseDown = FALSE; 02939 } 02940 break; 02941 } 02942 02943 02944 if (fChangedSel) { 02945 MLChangeSelection(ped, hdc, ichMinSel, ichMaxSel); 02946 MLEnsureCaretVisible(ped); 02947 } 02948 02949 ECReleaseEditDC(ped, hdc, TRUE); 02950 02951 if (!ped->fFocus && (message == WM_LBUTTONDOWN)) { 02952 02953 /* 02954 * If we don't have the focus yet, get it 02955 */ 02956 NtUserSetFocus(ped->hwnd); 02957 } 02958 }

ICH MLMouseToIch PED  ped,
HDC  hdc,
LPPOINT  mousePt,
LPICH  pline
 

Definition at line 689 of file editml.c.

References tagED::aveCharWidth, tagED::cbChar, tagED::chLines, tagED::cLines, ECAdjustIch(), ECCchInWidth(), ECLock(), ECUnlock(), tagLPKEDITCALLOUT::EditMouseToIch, tagED::fAnsi, tagED::fDBCS, tagED::format, ICH, tagED::ichLinesOnScreen, tagED::ichScreenStart, tagED::lineHeight, max, min, MLCalcXOffset(), MLGetLineWidth(), MLLine(), tagED::pLpkEditCallout, tagED::rcFmt, TRUE, and tagED::xOffset.

Referenced by MLEditWndProc(), MLMouseMotion(), and MLPaint().

00694 { 00695 int xOffset; 00696 LPSTR pLineStart; 00697 int height = mousePt->y; 00698 int line; //WASINT 00699 int width = mousePt->x; 00700 ICH cch; 00701 ICH cLineLength; 00702 ICH cLineLengthNew; 00703 ICH cLineLengthHigh; 00704 ICH cLineLengthLow; 00705 ICH cLineLengthTemp; 00706 int textWidth; 00707 int iCurWidth; 00708 int lastHighWidth, lastLowWidth; 00709 00710 /* 00711 * First determine which line the mouse is pointing to. 00712 */ 00713 line = ped->ichScreenStart; 00714 if (height <= ped->rcFmt.top) { 00715 00716 /* 00717 * Either return 0 (the very first line, or one line before the top line 00718 * on the screen. Note that these are signed mins and maxes since we 00719 * don't expect (or allow) more than 32K lines. 00720 */ 00721 line = max(0, line-1); 00722 } else if (height >= ped->rcFmt.bottom) { 00723 00724 /* 00725 * Are we below the last line displayed 00726 */ 00727 line = min(line+(int)ped->ichLinesOnScreen, (int)(ped->cLines-1)); 00728 } else { 00729 00730 /* 00731 * We are somewhere on a line visible on screen 00732 */ 00733 line = min(line + (int)((height - ped->rcFmt.top) / ped->lineHeight), 00734 (int)(ped->cLines - 1)); 00735 } 00736 00737 /* 00738 * Now determine what horizontal character the mouse is pointing to. 00739 */ 00740 pLineStart = ECLock(ped) + ped->chLines[line] * ped->cbChar; 00741 cLineLength = MLLine(ped, line); /* Length is sans CRLF or CRCRLF */ 00742 RIPMSG3(RIP_VERBOSE, "MLLine(ped=%x, line=%d) returned %d\n", ped, line, cLineLength); 00743 UserAssert((int)cLineLength >= 0); 00744 00745 /* 00746 * If the language pack is loaded, visual and logical character order 00747 * may differ. 00748 */ 00749 if (ped->pLpkEditCallout) { 00750 /* 00751 * Use the language pack to find the character nearest the cursor. 00752 */ 00753 cch = ped->chLines[line] + ped->pLpkEditCallout->EditMouseToIch 00754 (ped, hdc, pLineStart, cLineLength, width); 00755 } else { 00756 /* 00757 * xOffset will be a negative value for center and right justified lines. 00758 * ie. We will just displace the lines left by the amount of indent for 00759 * right and center justification. Note that ped->xOffset will be 0 for 00760 * these lines since we don't support horizontal scrolling with them. 00761 */ 00762 if (ped->format != ES_LEFT) { 00763 xOffset = MLCalcXOffset(ped, hdc, line); 00764 } else { 00765 /* 00766 * So that we handle a horizontally scrolled window for left justified 00767 * text. 00768 */ 00769 xOffset = 0; 00770 } 00771 00772 width = width - xOffset; 00773 00774 /* 00775 * The code below is tricky... I depend on the fact that ped->xOffset is 0 00776 * for right and center justified lines 00777 */ 00778 00779 /* 00780 * Now find out how many chars fit in the given width 00781 */ 00782 if (width >= ped->rcFmt.right) { 00783 00784 /* 00785 * Return 1+last char in line or one plus the last char visible 00786 */ 00787 cch = ECCchInWidth(ped, hdc, pLineStart, cLineLength, 00788 ped->rcFmt.right - ped->rcFmt.left + ped->xOffset, TRUE); 00789 // 00790 // Consider DBCS in case of width >= ped->rcFmt.right 00791 // 00792 // Since ECCchInWidth and MLLineLength takes care of DBCS, we only need to 00793 // worry about if the last character is a double byte character or not. 00794 // 00795 // cch = ped->chLines[line] + min( ECNextIch(ped, pLineStart, cch), cLineLength); 00796 // 00797 // we need to adjust the position. LiZ -- 5/5/93 00798 if (ped->fAnsi && ped->fDBCS) { 00799 ICH cch2 = min(cch+1,cLineLength); 00800 if (ECAdjustIch(ped, pLineStart, cch2) != cch2) { 00801 /* Displayed character on the right edge is DBCS */ 00802 cch = min(cch+2,cLineLength); 00803 } else { 00804 cch = cch2; 00805 } 00806 cch += ped->chLines[line]; 00807 } else { 00808 cch = ped->chLines[line] + min(cch + 1, cLineLength); 00809 } 00810 } else if (width <= ped->rcFmt.left + ped->aveCharWidth / 2) { 00811 00812 /* 00813 * Return first char in line or one minus first char visible. Note that 00814 * ped->xOffset is 0 for right and centered text so we will just return 00815 * the first char in the string for them. (Allow a avecharwidth/2 00816 * positioning border so that the user can be a little off... 00817 */ 00818 cch = ECCchInWidth(ped, hdc, pLineStart, cLineLength, 00819 ped->xOffset, TRUE); 00820 if (cch) 00821 cch--; 00822 00823 cch = ECAdjustIch( ped, pLineStart, cch ); 00824 cch += ped->chLines[line]; 00825 } else { 00826 00827 if (cLineLength == 0) { 00828 cch = ped->chLines[line]; 00829 goto edUnlock; 00830 } 00831 00832 iCurWidth = width + ped->xOffset - ped->rcFmt.left; 00833 /* 00834 * If the user clicked past the end of the text, return the last character 00835 */ 00836 lastHighWidth = MLGetLineWidth(hdc, pLineStart, cLineLength, ped); 00837 if (lastHighWidth <= iCurWidth) { 00838 cLineLengthNew = cLineLength; 00839 goto edAdjust; 00840 } 00841 /* 00842 * Now the mouse is somewhere on the visible portion of the text 00843 * remember cch contains the length of the line. 00844 */ 00845 cLineLengthLow = 0; 00846 cLineLengthHigh = cLineLength + 1; 00847 lastLowWidth = 0; 00848 00849 while (cLineLengthLow < cLineLengthHigh - 1) { 00850 00851 cLineLengthNew = (cLineLengthHigh + cLineLengthLow) / 2; 00852 00853 if (ped->fAnsi && ped->fDBCS) { 00854 /* 00855 * MLGetLineWidth returns meaningless value for truncated DBCS. 00856 */ 00857 cLineLengthTemp = ECAdjustIch(ped, pLineStart, cLineLengthNew); 00858 textWidth = MLGetLineWidth(hdc, pLineStart, cLineLengthTemp, ped); 00859 00860 } else { 00861 textWidth = MLGetLineWidth(hdc, pLineStart, cLineLengthNew, ped); 00862 } 00863 00864 if (textWidth > iCurWidth) { 00865 cLineLengthHigh = cLineLengthNew; 00866 lastHighWidth = textWidth; 00867 } else { 00868 cLineLengthLow = cLineLengthNew; 00869 lastLowWidth = textWidth; 00870 } 00871 } 00872 00873 /* 00874 * When the while ends, you can't know the exact desired position. 00875 * Try to see if the mouse pointer was on the farest half 00876 * of the char we got and if so, adjust cch. 00877 */ 00878 if (cLineLengthLow == cLineLengthNew) { 00879 /* 00880 * Need to compare with lastHighWidth 00881 */ 00882 if ((lastHighWidth - iCurWidth) < (iCurWidth - textWidth)) { 00883 cLineLengthNew++; 00884 } 00885 } else { 00886 /* 00887 * Need to compare with lastLowHigh 00888 */ 00889 if ((iCurWidth - lastLowWidth) < (textWidth - iCurWidth)) { 00890 cLineLengthNew--; 00891 } 00892 } 00893 edAdjust: 00894 cLineLength = ECAdjustIch( ped, pLineStart, cLineLengthNew ); 00895 00896 cch = ped->chLines[line] + cLineLength; 00897 } 00898 } 00899 edUnlock: 00900 ECUnlock(ped); 00901 00902 if (pline) { 00903 *pline = line; 00904 } 00905 return cch; 00906 }

ICH MLMoveSelection PED  ped,
ICH  ich,
BOOL  fLeft
 

Definition at line 144 of file editml.c.

References tagED::cch, ECLock(), ECNextIch(), ECPrevIch(), ECUnlock(), tagED::fAnsi, ICH, and NULL.

Referenced by MLChar(), and MLKeyDown().

00148 { 00149 00150 if (fLeft && ich > 0) { 00151 00152 /* 00153 * Move left 00154 */ 00155 ich = ECPrevIch( ped, NULL, ich ); 00156 if (ich) { 00157 if (ped->fAnsi) { 00158 LPSTR pText; 00159 00160 /* 00161 * Check for CRLF or CRCRLF 00162 */ 00163 pText = ECLock(ped) + ich; 00164 00165 /* 00166 * Move before CRLF or CRCRLF 00167 */ 00168 if (*(WORD UNALIGNED *)(pText - 1) == 0x0A0D) { 00169 ich--; 00170 if (ich && *(pText - 2) == 0x0D) 00171 ich--; 00172 } 00173 ECUnlock(ped); 00174 } else { // !fAnsi 00175 LPWSTR pwText; 00176 00177 /* 00178 * Check for CRLF or CRCRLF 00179 */ 00180 pwText = (LPWSTR)ECLock(ped) + ich; 00181 00182 /* 00183 * Move before CRLF or CRCRLF 00184 */ 00185 if (*(pwText - 1) == 0x0D && *pwText == 0x0A) { 00186 ich--; 00187 if (ich && *(pwText - 2) == 0x0D) 00188 ich--; 00189 } 00190 ECUnlock(ped); 00191 } 00192 } 00193 } else if (!fLeft && ich < ped->cch) { 00194 /* 00195 * Move right. 00196 */ 00197 ich = ECNextIch( ped, NULL, ich ); 00198 if (ich < ped->cch) { 00199 if (ped->fAnsi) { 00200 LPSTR pText; 00201 pText = ECLock(ped) + ich; 00202 00203 /* 00204 * Move after CRLF 00205 */ 00206 if (*(WORD UNALIGNED *)(pText - 1) == 0x0A0D) 00207 ich++; 00208 else { 00209 00210 /* 00211 * Check for CRCRLF 00212 */ 00213 if (ich && *(WORD UNALIGNED *)pText == 0x0A0D && *(pText - 1) == 0x0D) 00214 ich += 2; 00215 } 00216 ECUnlock(ped); 00217 } else { // !fAnsi 00218 LPWSTR pwText; 00219 pwText = (LPWSTR)ECLock(ped) + ich; 00220 00221 /* 00222 * Move after CRLF 00223 */ 00224 if (*(pwText - 1) == 0x0D && *pwText == 0x0A) 00225 ich++; 00226 else { 00227 00228 /* 00229 * Check for CRCRLF 00230 */ 00231 if (ich && *(pwText - 1) == 0x0D && *pwText == 0x0D && 00232 *(pwText + 1) == 0x0A) 00233 ich += 2; 00234 } 00235 ECUnlock(ped); 00236 } 00237 } 00238 } 00239 return (ich); 00240 }

ICH MLMoveSelectionRestricted PED  ped,
ICH  ich,
BOOL  fLeft
 

Definition at line 264 of file editml.c.

References ECGetEditDC(), ECLock(), ECReleaseEditDC(), ECUnlock(), tagLPKEDITCALLOUT::EditMoveSelection, ICH, tagED::pLpkEditCallout, and TRUE.

Referenced by MLKeyDown().

00268 { 00269 PSTR pText; 00270 HDC hdc; 00271 ICH ichResult; 00272 00273 pText = ECLock(ped); 00274 hdc = ECGetEditDC(ped, TRUE); 00275 ichResult = ped->pLpkEditCallout->EditMoveSelection(ped, hdc, pText, ich, fLeft); 00276 ECReleaseEditDC(ped, hdc, TRUE); 00277 ECUnlock(ped); 00278 00279 return ichResult; 00280 }

void MLPaint PED  ped,
HDC  hdc,
LPRECT  lprc
 

Definition at line 1965 of file editml.c.

References _GetClientRect(), BOOL, tagED::cch, DF_WINDOWFRAME, DrawFrame(), ECSetEditClip(), FALSE, tagED::fFlatBorder, tagED::hFont, ICH, InflateRect(), MLDrawText(), MLMouseToIch(), NULL, tagED::pwnd, SYSMET, TestWF, WFSIZEBOX, and tagED::xOffset.

Referenced by MLEditWndProc().

01966 { 01967 HFONT hOldFont; 01968 ICH imin; 01969 ICH imax; 01970 01971 // 01972 // Do we need to draw the border ourself for old apps? 01973 // 01974 if (ped->fFlatBorder) 01975 { 01976 RECT rcT; 01977 01978 _GetClientRect(ped->pwnd, &rcT); 01979 if (TestWF(ped->pwnd, WFSIZEBOX)) 01980 { 01981 InflateRect(&rcT, SYSMET(CXBORDER) - SYSMET(CXFRAME), 01982 SYSMET(CYBORDER) - SYSMET(CYFRAME)); 01983 } 01984 DrawFrame(hdc, &rcT, 1, DF_WINDOWFRAME); 01985 } 01986 01987 ECSetEditClip(ped, hdc, (BOOL) (ped->xOffset == 0)); 01988 01989 if (ped->hFont) 01990 hOldFont = SelectObject(hdc, ped->hFont); 01991 01992 if (!lprc) { 01993 // no partial rect given -- draw all text 01994 imin = 0; 01995 imax = ped->cch; 01996 } else { 01997 // only draw pertinent text 01998 imin = (ICH) MLMouseToIch(ped, hdc, ((LPPOINT) &lprc->left), NULL) - 1; 01999 if (imin == -1) 02000 imin = 0; 02001 02002 // HACK_ALERT: 02003 // The 3 is required here because, MLMouseToIch() returns decremented 02004 // value; We must fix MLMouseToIch. 02005 imax = (ICH) MLMouseToIch(ped, hdc, ((LPPOINT) &lprc->right), NULL) + 3; 02006 if (imax > ped->cch) 02007 imax = ped->cch; 02008 } 02009 02010 MLDrawText(ped, hdc, imin, imax, FALSE); 02011 02012 if (ped->hFont) 02013 SelectObject(hdc, hOldFont); 02014 }

ICH PASCAL NEAR MLPasteText PED  ped  ) 
 

Definition at line 2720 of file editml.c.

References ECEmptyUndo(), FALSE, tagED::fAnsi, tagED::fAutoVScroll, GetClipboardData(), tagED::hwnd, ICH, MLDeleteText(), MLInsertText(), NtUserCloseClipboard(), NtUserSetCursor(), NULL, OpenClipboard(), strlen(), USERGLOBALLOCK, and USERGLOBALUNLOCK.

Referenced by MLEditWndProc().

02722 { 02723 HANDLE hData; 02724 LPSTR lpchClip; 02725 ICH cchAdded = 0; 02726 HCURSOR hCursorOld; 02727 02728 #ifdef UNDO_CLEANUP // #ifdef Added in Chicago - johnl 02729 if (!ped->fAutoVScroll) { 02730 02731 /* 02732 * Empty the undo buffer if this edit control limits the amount of text 02733 * the user can add to the window rect. This is so that we can undo this 02734 * operation if doing in causes us to exceed the window boundaries. 02735 */ 02736 ECEmptyUndo(ped); 02737 } 02738 #endif 02739 02740 hCursorOld = NtUserSetCursor(LoadCursor(NULL, IDC_WAIT)); 02741 02742 if (!OpenClipboard(ped->hwnd)) 02743 goto PasteExitNoCloseClip; 02744 02745 if (!(hData = GetClipboardData(ped->fAnsi ? CF_TEXT : CF_UNICODETEXT)) || 02746 (GlobalFlags(hData) == GMEM_INVALID_HANDLE)) { 02747 RIPMSG1(RIP_WARNING, "MLPasteText(): couldn't get a valid handle(%x)", hData); 02748 goto PasteExit; 02749 } 02750 02751 /* 02752 * See if any text should be deleted 02753 */ 02754 MLDeleteText(ped); 02755 02756 USERGLOBALLOCK(hData, lpchClip); 02757 if (lpchClip == NULL) { 02758 RIPMSG1(RIP_WARNING, "MLPasteText: USERGLOBALLOCK(%x) failed.", hData); 02759 goto PasteExit; 02760 } 02761 02762 /* 02763 * Get the length of the addition. 02764 */ 02765 if (ped->fAnsi) 02766 cchAdded = strlen(lpchClip); 02767 else 02768 cchAdded = wcslen((LPWSTR)lpchClip); 02769 02770 /* 02771 * Insert the text (MLInsertText checks line length) 02772 */ 02773 cchAdded = MLInsertText(ped, lpchClip, cchAdded, FALSE); 02774 02775 USERGLOBALUNLOCK(hData); 02776 02777 PasteExit: 02778 NtUserCloseClipboard(); 02779 02780 PasteExitNoCloseClip: 02781 NtUserSetCursor(hCursorOld); 02782 02783 return (cchAdded); 02784 }

void MLReplaceSel PED  ped,
LPSTR  lpText
 

Definition at line 1309 of file editml.c.

References BOOL, ECEmptyUndo(), ECSaveUndo(), FALSE, tagED::fAnsi, tagED::hwnd, ICH, IsWindow(), MLDeleteText(), MLInsertText(), MLUndo(), Pundo, and strlen().

Referenced by ECResultStrHandler(), and MLEditWndProc().

01310 { 01311 ICH cchText; 01312 01313 // 01314 // Delete text, which will put it into the clean undo buffer. 01315 // 01316 ECEmptyUndo(Pundo(ped)); 01317 MLDeleteText(ped); 01318 01319 // 01320 // B#3356 01321 // Some apps do "clear" by selecting all of the text, then replacing 01322 // it with "", in which case MLInsertText() will return 0. But that 01323 // doesn't mean failure... 01324 // 01325 if ( ped->fAnsi ) 01326 cchText = strlen(lpText); 01327 else 01328 cchText = wcslen((LPWSTR)lpText); 01329 01330 if (cchText ) { 01331 BOOL fFailed; 01332 UNDO undo; 01333 HWND hwndSave; 01334 01335 // 01336 // B#1385,1427 01337 // Save undo buffer, but DO NOT CLEAR IT. We want to restore it 01338 // if insertion fails due to OOM. 01339 // 01340 ECSaveUndo(Pundo(ped), (PUNDO)&undo, FALSE); 01341 01342 hwndSave = ped->hwnd; 01343 fFailed = (BOOL) !MLInsertText(ped, lpText, cchText, FALSE); 01344 if (!IsWindow(hwndSave)) 01345 return; 01346 01347 if (fFailed) { 01348 // 01349 // UNDO the previous edit 01350 // 01351 ECSaveUndo((PUNDO)&undo, Pundo(ped), FALSE); 01352 MLUndo(ped); 01353 } 01354 } 01355 }

__inline void MLSanityCheck PED  ped  ) 
 

Definition at line 24 of file editml.c.

References tagED::cch, tagED::chLines, and tagED::cLines.

Referenced by MLBuildchLines().

00025 { 00026 UNREFERENCED_PARAMETER(ped); // For free build 00027 00028 UserAssert(ped->cch >= ped->chLines[ped->cLines - 1]); 00029 }

LONG MLScroll PED  ped,
BOOL  fVertical,
int  cmd,
int  iAmt,
BOOL  fRedraw
 

Definition at line 2966 of file editml.c.

References _GetClientRect(), _IsWindowVisible(), tagED::aveCharWidth, BOOL, tagED::cLines, CopyRect, DWORD, ECGetBrush(), ECGetEditDC(), ECNotifyParent(), ECReleaseEditDC(), ECSetEditClip(), FALSE, tagED::format, tagED::fRtoLReading, GetScrollInfo(), tagED::hFont, tagED::hwnd, tagED::hwndParent, tagED::ichLinesOnScreen, tagED::ichScreenStart, IntersectRect(), L, tagED::lineHeight, max, tagED::maxPixelWidth, min, ML_REFRESH, MLSetCaretPosition(), NtUserInvalidateRect(), NtUserScrollDC(), NtUserSetScrollInfo(), NULL, tagED::pLpkEditCallout, tagED::pwnd, tagED::rcFmt, ScrollWindowEx(), TestWF, TRUE, UINT, UnionRect(), UpdateWindow(), ValidateHwnd, WFHSCROLL, WFVSCROLL, WFWIN40COMPAT, tagED::wLeftMargin, tagED::wRightMargin, and tagED::xOffset.

Referenced by ECUpdateFormat(), MLBuildchLines(), MLEditWndProc(), MLEnsureCaretVisible(), and MLSize().

02972 { 02973 SCROLLINFO si; 02974 int dx = 0; 02975 int dy = 0; 02976 BOOL fIncludeLeftMargin; 02977 int newPos; 02978 int oldPos; 02979 BOOL fUp = FALSE; 02980 UINT wFlag; 02981 DWORD dwTime = 0; 02982 02983 if (fRedraw && (cmd != ML_REFRESH)) { 02984 UpdateWindow(ped->hwnd); 02985 } 02986 02987 if (ped->pLpkEditCallout && ped->fRtoLReading && !fVertical 02988 && ped->maxPixelWidth > ped->rcFmt.right - ped->rcFmt.left) { 02989 /* 02990 * Horizontal scoll of a right oriented window with a scrollbar. 02991 * Map the logical xOffset to visual coordinates. 02992 */ 02993 oldPos = ped->maxPixelWidth 02994 - ((int)ped->xOffset + ped->rcFmt.right - ped->rcFmt.left); 02995 } else 02996 oldPos = (int) (fVertical ? ped->ichScreenStart : ped->xOffset); 02997 02998 fIncludeLeftMargin = (ped->xOffset == 0); 02999 03000 switch (cmd) { 03001 case ML_REFRESH: 03002 newPos = oldPos; 03003 break; 03004 03005 case EM_GETTHUMB: 03006 return(oldPos); 03007 03008 case SB_THUMBTRACK: 03009 case SB_THUMBPOSITION: 03010 03011 /* 03012 * If the edit contains more than 0xFFFF lines 03013 * it means that the scrolbar can return a position 03014 * that cannot fit in a WORD (16 bits), so use 03015 * GetScrollInfo (which is slower) in this case. 03016 */ 03017 if (ped->cLines < 0xFFFF) { 03018 newPos = iAmt; 03019 } else { 03020 SCROLLINFO si; 03021 03022 si.cbSize = sizeof(SCROLLINFO); 03023 si.fMask = SIF_TRACKPOS; 03024 03025 GetScrollInfo( ped->hwnd, SB_VERT, &si); 03026 03027 newPos = si.nTrackPos; 03028 } 03029 break; 03030 03031 case SB_TOP: // == SB_LEFT 03032 newPos = 0; 03033 break; 03034 03035 case SB_BOTTOM: // == SB_RIGHT 03036 if (fVertical) 03037 newPos = ped->cLines; 03038 else 03039 newPos = ped->maxPixelWidth; 03040 break; 03041 03042 case SB_PAGEUP: // == SB_PAGELEFT 03043 fUp = TRUE; 03044 case SB_PAGEDOWN: // == SB_PAGERIGHT 03045 03046 if (fVertical) 03047 iAmt = ped->ichLinesOnScreen - 1; 03048 else 03049 iAmt = (ped->rcFmt.right - ped->rcFmt.left) - 1; 03050 03051 if (iAmt == 0) 03052 iAmt++; 03053 03054 if (fUp) 03055 iAmt = -iAmt; 03056 goto AddDelta; 03057 03058 case SB_LINEUP: // == SB_LINELEFT 03059 fUp = TRUE; 03060 case SB_LINEDOWN: // == SB_LINERIGHT 03061 03062 dwTime = iAmt; 03063 03064 iAmt = 1; 03065 03066 if (fUp) 03067 iAmt = -iAmt; 03068 03069 // | | 03070 // | FALL THRU | 03071 // V V 03072 03073 case EM_LINESCROLL: 03074 if (!fVertical) 03075 iAmt *= ped->aveCharWidth; 03076 03077 AddDelta: 03078 newPos = oldPos + iAmt; 03079 break; 03080 03081 default: 03082 return(0L); 03083 } 03084 03085 if (fVertical) { 03086 if (si.nMax = ped->cLines) 03087 si.nMax--; 03088 03089 if (!ped->hwndParent || 03090 TestWF(ValidateHwnd(ped->hwndParent), WFWIN40COMPAT)) 03091 si.nPage = ped->ichLinesOnScreen; 03092 else 03093 si.nPage = 0; 03094 03095 wFlag = WFVSCROLL; 03096 } else { 03097 si.nMax = ped->maxPixelWidth; 03098 si.nPage = ped->rcFmt.right - ped->rcFmt.left; 03099 wFlag = WFHSCROLL; 03100 } 03101 03102 if (TestWF(ValidateHwnd(ped->hwnd), wFlag)) { 03103 si.cbSize = sizeof(SCROLLINFO); 03104 si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; 03105 si.nMin = 0; 03106 si.nPos = newPos; 03107 newPos = NtUserSetScrollInfo(ped->hwnd, fVertical ? SB_VERT : SB_HORZ, 03108 &si, fRedraw); 03109 } else { 03110 // BOGUS -- this is duped code from ScrollBar code 03111 // but it's for the case when we want to limit the position without 03112 // actually having the scroll bar 03113 int iMaxPos; 03114 03115 // Clip page to 0, range + 1 03116 si.nPage = max(min((int)si.nPage, si.nMax + 1), 0); 03117 03118 03119 iMaxPos = si.nMax - (si.nPage ? si.nPage - 1 : 0); 03120 newPos = min(max(newPos, 0), iMaxPos); 03121 } 03122 03123 oldPos -= newPos; 03124 03125 if (!oldPos) 03126 return(0L); 03127 03128 if (ped->pLpkEditCallout && ped->fRtoLReading && !fVertical 03129 && ped->maxPixelWidth > ped->rcFmt.right - ped->rcFmt.left) { 03130 // Map visual oldPos and newPos back to logical coordinates 03131 newPos = ped->maxPixelWidth 03132 - (newPos + ped->rcFmt.right - ped->rcFmt.left); 03133 oldPos = -oldPos; 03134 if (newPos<0) { 03135 // Compensate for scroll bar returning pos > max-page 03136 oldPos += newPos; 03137 newPos=0; 03138 } 03139 } 03140 03141 if (fVertical) { 03142 ped->ichScreenStart = newPos; 03143 dy = oldPos * ped->lineHeight; 03144 } else { 03145 ped->xOffset = newPos; 03146 dx = oldPos; 03147 } 03148 03149 if (cmd != SB_THUMBTRACK) 03150 // We don't want to notify the parent of thumbtracking since they might 03151 // try to set the thumb position to something bogus. 03152 // NOTEPAD used to be guilty of this -- but I rewrote it so it's not. 03153 // The question is WHO ELSE does this? (jeffbog) 03154 ECNotifyParent(ped, fVertical ? EN_VSCROLL : EN_HSCROLL); 03155 03156 if (fRedraw && _IsWindowVisible(ped->pwnd)) { 03157 RECT rc; 03158 RECT rcUpdate; 03159 RECT rcClipRect; 03160 HDC hdc; 03161 03162 _GetClientRect(ped->pwnd, &rc); 03163 CopyRect(&rcClipRect, &ped->rcFmt); 03164 03165 if (fVertical) { // Is this a vertical scroll? 03166 rcClipRect.left -= ped->wLeftMargin; 03167 rcClipRect.right += ped->wRightMargin; 03168 } 03169 03170 IntersectRect(&rc, &rc, &rcClipRect); 03171 rc.bottom++; 03172 03173 /* 03174 * Chicago has this HideCaret but there doesn't appear to be a 03175 * corresponding ShowCaret, so we lose the Caret under NT when the 03176 * EC scrolls - Johnl 03177 * 03178 * HideCaret(ped->hwnd); 03179 */ 03180 03181 hdc = ECGetEditDC(ped, FALSE); 03182 ECSetEditClip(ped, hdc, fIncludeLeftMargin); 03183 if (ped->hFont) 03184 SelectObject(hdc, ped->hFont); 03185 ECGetBrush(ped, hdc); 03186 03187 if (ped->pLpkEditCallout && !fVertical) { 03188 // Horizontal scroll with complex script support 03189 int xFarOffset = ped->xOffset + ped->rcFmt.right - ped->rcFmt.left; 03190 03191 rc = ped->rcFmt; 03192 if (dwTime != 0) 03193 ScrollWindowEx(ped->hwnd, ped->fRtoLReading ? -dx : dx, dy, NULL, NULL, NULL, 03194 &rcUpdate, MAKELONG(SW_SMOOTHSCROLL | SW_SCROLLCHILDREN, dwTime)); 03195 else 03196 NtUserScrollDC(hdc, ped->fRtoLReading ? -dx : dx, dy, 03197 &rc, &rc, NULL, &rcUpdate); 03198 03199 // Handle margins: Blank if clipped by horizontal scrolling, 03200 // display otherwise. 03201 if (ped->wLeftMargin) { 03202 rc.left = ped->rcFmt.left - ped->wLeftMargin; 03203 rc.right = ped->rcFmt.left; 03204 if ( (ped->format != ES_LEFT) // Always display margin for centred or far-aligned text 03205 || // Display LTR left margin if first character fully visible 03206 (!ped->fRtoLReading && ped->xOffset == 0) 03207 || // Display RTL left margin if last character fully visible 03208 (ped->fRtoLReading && xFarOffset >= ped->maxPixelWidth)) { 03209 UnionRect(&rcUpdate, &rcUpdate, &rc); 03210 } else { 03211 ExtTextOutW(hdc, rc.left, rc.top, 03212 ETO_CLIPPED | ETO_OPAQUE | ETO_GLYPH_INDEX, 03213 &rc, L"", 0, 0L); 03214 } 03215 } 03216 if (ped->wRightMargin) { 03217 rc.left = ped->rcFmt.right; 03218 rc.right = ped->rcFmt.right + ped->wRightMargin; 03219 if ( (ped->format != ES_LEFT) // Always display margin for centred or far-aligned text 03220 || // Display RTL right margin if first character fully visible 03221 (ped->fRtoLReading && ped->xOffset == 0) 03222 || // Display LTR right margin if last character fully visible 03223 (!ped->fRtoLReading && xFarOffset >= ped->maxPixelWidth)) { 03224 UnionRect(&rcUpdate, &rcUpdate, &rc); 03225 } else { 03226 ExtTextOutW(hdc, rc.left, rc.top, 03227 ETO_CLIPPED | ETO_OPAQUE | ETO_GLYPH_INDEX, 03228 &rc, L"", 0, 0L); 03229 } 03230 } 03231 } else { 03232 if (dwTime != 0) 03233 ScrollWindowEx(ped->hwnd, dx, dy, NULL, NULL, NULL, 03234 &rcUpdate, MAKELONG(SW_SMOOTHSCROLL | SW_SCROLLCHILDREN, dwTime)); 03235 else 03236 NtUserScrollDC(hdc, dx, dy, &rc, &rc, NULL, &rcUpdate); 03237 03238 // If we need to wipe out the left margin area 03239 if (ped->wLeftMargin && !fVertical) { 03240 // Calculate the rectangle to be wiped out 03241 rc.right = rc.left; 03242 rc.left = max(0, ped->rcFmt.left - ped->wLeftMargin); 03243 if (rc.left < rc.right) { 03244 if (fIncludeLeftMargin && (ped->xOffset != 0)) { 03245 03246 ExtTextOutW(hdc, rc.left, rc.top, ETO_CLIPPED | ETO_OPAQUE, 03247 &rc, L"", 0, 0L); 03248 } else 03249 if((!fIncludeLeftMargin) && (ped->xOffset == 0)) 03250 UnionRect(&rcUpdate, &rcUpdate, &rc); 03251 } 03252 } 03253 } 03254 MLSetCaretPosition(ped,hdc); 03255 03256 ECReleaseEditDC(ped, hdc, FALSE); 03257 NtUserInvalidateRect(ped->hwnd, &rcUpdate, 03258 ((ped->ichLinesOnScreen + ped->ichScreenStart) >= ped->cLines)); 03259 UpdateWindow(ped->hwnd); 03260 } 03261 03262 return(MAKELONG(-oldPos, 1)); 03263 }

void MLSetCaretPosition PED  ped,
HDC  hdc
 

Definition at line 292 of file editml.c.

References _IsWindowVisible(), BOOL, tagED::chLines, tagED::cLines, CopyRect, ECGetCaretWidth, ECImmSetCompositionWindow(), tagED::f40Compat, FALSE, tagED::fCaretHidden, tagED::fFocus, fpImmIsIME, tagED::fWrap, GetClientRect(), tagED::hwnd, tagED::iCaretLine, tagED::iCaretOffset, ICH, tagED::ichCaret, tagED::ichLinesOnScreen, tagED::ichScreenStart, IntersectRect(), tagED::lineHeight, max, min, MLIchToXYPos(), NtUserSetCaretPos, tagED::pLpkEditCallout, tagED::pwnd, tagED::rcFmt, THREAD_HKL, and TRUE.

Referenced by ECSetCaretHandler(), MLChangeSelection(), MLDrawText(), MLEditWndProc(), MLKeyDown(), MLMouseMotion(), MLScroll(), MLSetFocus(), and MLSetSelection().

00295 { 00296 POINT position; 00297 BOOL prevLine; 00298 int x = -20000; 00299 int y = -20000; 00300 00301 /* 00302 * We will only position the caret if we have the focus since we don't want 00303 * to move the caret while another window could own it. 00304 */ 00305 if (!ped->fFocus || !_IsWindowVisible(ped->pwnd)) 00306 return; 00307 00308 /* 00309 * Find the position of the caret 00310 */ 00311 if (!ped->fCaretHidden && 00312 ((ICH) ped->iCaretLine >= ped->ichScreenStart) && 00313 ((ICH) ped->iCaretLine < (ped->ichScreenStart + ped->ichLinesOnScreen))) { 00314 00315 RECT rcRealFmt; 00316 00317 if (ped->f40Compat) 00318 { 00319 GetClientRect(ped->hwnd, &rcRealFmt); 00320 IntersectRect(&rcRealFmt, &rcRealFmt, &ped->rcFmt); 00321 } else { 00322 CopyRect(&rcRealFmt, &ped->rcFmt); 00323 } 00324 00325 if (ped->cLines - 1 != ped->iCaretLine && ped->ichCaret == ped->chLines[ped->iCaretLine + 1]) { 00326 prevLine = TRUE; 00327 } else { 00328 prevLine = FALSE; 00329 } 00330 00331 MLIchToXYPos(ped, hdc, ped->ichCaret, prevLine, &position); 00332 00333 if ( (position.y >= rcRealFmt.top) && 00334 (position.y <= rcRealFmt.bottom - ped->lineHeight)) { 00335 int xPos = position.x; 00336 int cxCaret = ECGetCaretWidth(); 00337 00338 if (ped->fWrap || 00339 ((xPos > (rcRealFmt.left - cxCaret)) && 00340 (xPos <= rcRealFmt.right))) { 00341 // Make sure the caret is in the visible region if word 00342 // wrapping. This is so that the caret will be visible if the 00343 // line ends with a space. 00344 x = max(xPos, rcRealFmt.left); 00345 x = min(x, rcRealFmt.right - cxCaret); 00346 y = position.y; 00347 } 00348 } 00349 } 00350 00351 if (ped->pLpkEditCallout) { 00352 NtUserSetCaretPos(x + ped->iCaretOffset, y); 00353 } else { 00354 NtUserSetCaretPos(x, y); 00355 } 00356 00357 // FE_IME : MLSetCaretPosition -- ImmSetCompositionWindow(CFS_RECT) 00358 if (fpImmIsIME(THREAD_HKL())) { 00359 if (x != -20000 && y != -20000) { 00360 ECImmSetCompositionWindow(ped, x, y); 00361 } 00362 } 00363 }

void MLSetFocus PED  ped  ) 
 

Definition at line 3274 of file editml.c.

References _IsWindowVisible(), ECGetCaretWidth, ECGetEditDC(), ECNotifyParent(), ECReleaseEditDC(), tagLPKEDITCALLOUT::EditCreateCaret, tagED::fFocus, tagED::fNoHideSel, tagED::hwnd, tagED::ichMaxSel, tagED::ichMinSel, tagED::lineHeight, MLDrawText(), MLEnsureCaretVisible(), MLSetCaretPosition(), NtUserCreateCaret(), NtUserShowCaret(), NULL, tagED::pLpkEditCallout, tagED::pwnd, and TRUE.

Referenced by MLEditWndProc().

03276 { 03277 HDC hdc; 03278 03279 if (!ped->fFocus) { 03280 ped->fFocus = 1; /* Set focus */ 03281 03282 hdc = ECGetEditDC(ped, TRUE); 03283 03284 /* 03285 * Draw the caret. We need to do this even if the window is hidden 03286 * because in dlg box initialization time we may set the focus to a 03287 * hidden edit control window. If we don't create the caret etc, it will 03288 * never end up showing properly. 03289 */ 03290 if (ped->pLpkEditCallout) { 03291 ped->pLpkEditCallout->EditCreateCaret (ped, hdc, ECGetCaretWidth(), ped->lineHeight, 0); 03292 } 03293 else { 03294 NtUserCreateCaret(ped->hwnd, (HBITMAP)NULL, ECGetCaretWidth(), ped->lineHeight); 03295 } 03296 NtUserShowCaret(ped->hwnd); 03297 MLSetCaretPosition(ped, hdc); 03298 03299 /* 03300 * Show the current selection. Only if the selection was hidden when we 03301 * lost the focus, must we invert (show) it. 03302 */ 03303 if (!ped->fNoHideSel && ped->ichMinSel != ped->ichMaxSel && 03304 _IsWindowVisible(ped->pwnd)) 03305 MLDrawText(ped, hdc, ped->ichMinSel, ped->ichMaxSel, TRUE); 03306 03307 ECReleaseEditDC(ped, hdc, TRUE); 03308 03309 } 03310 #if 0 03311 MLEnsureCaretVisible(ped); 03312 #endif 03313 03314 /* 03315 * Notify parent we have the focus 03316 */ 03317 ECNotifyParent(ped, EN_SETFOCUS); 03318 }

void MLShiftchLines PED  ped,
ICH  iLine,
int  delta
 

Definition at line 1538 of file editml.c.

References tagED::chLines, and tagED::cLines.

Referenced by MLBuildchLines(), and MLDeleteText().

01542 { 01543 if (iLine >= ped->cLines) 01544 return; 01545 01546 /* 01547 * Just add delta to the starting point of each line after iLine 01548 */ 01549 for (; iLine < ped->cLines; iLine++) 01550 ped->chLines[iLine] += delta; 01551 }

void MLSize PED  ped,
BOOL  fRedraw
 

Definition at line 56 of file editml.c.

References FALSE, tagED::fWrap, tagED::ichLinesOnScreen, tagED::lineHeight, ML_REFRESH, MLBuildchLines(), MLScroll(), MLUpdateiCaretLine(), NULL, tagED::rcFmt, and TRUE.

Referenced by ECSize().

00057 { 00058 // Calculate the # of lines we can fit in our rectangle. 00059 ped->ichLinesOnScreen = (ped->rcFmt.bottom - ped->rcFmt.top) / ped->lineHeight; 00060 00061 // Make the format rectangle height an integral number of lines 00062 ped->rcFmt.bottom = ped->rcFmt.top + ped->ichLinesOnScreen * ped->lineHeight; 00063 00064 // Rebuild the line array 00065 if (ped->fWrap) { 00066 MLBuildchLines(ped, 0, 0, FALSE, NULL, NULL); 00067 MLUpdateiCaretLine(ped); 00068 } else { 00069 MLScroll(ped, TRUE, ML_REFRESH, 0, fRedraw); 00070 MLScroll(ped, FALSE, ML_REFRESH, 0, fRedraw); 00071 } 00072 }

void MLUpdateiCaretLine PED  ped  ) 
 

Definition at line 1003 of file editml.c.

References AWCOMPARECHAR, tagED::cbChar, tagED::chLines, ECLock(), ECUnlock(), tagED::iCaretLine, tagED::ichCaret, and MLIchToLine().

Referenced by ECUpdateFormat(), MLDeleteText(), MLInsertText(), MLSetTabStops(), and MLSize().

01004 { 01005 PSTR pText; 01006 01007 ped->iCaretLine = MLIchToLine(ped, ped->ichCaret); 01008 01009 /* 01010 * If caret gets to beginning of next line, pop it up to end of current line 01011 * when inserting text. 01012 */ 01013 pText = ECLock(ped) + 01014 (ped->ichCaret - 1) * ped->cbChar; 01015 if (ped->iCaretLine && ped->chLines[ped->iCaretLine] == ped->ichCaret && 01016 (!AWCOMPARECHAR(ped, pText - ped->cbChar, 0x0D) || 01017 !AWCOMPARECHAR(ped, pText, 0x0A))) 01018 ped->iCaretLine--; 01019 ECUnlock(ped); 01020 }


Generated on Sat May 15 19:43:32 2004 for test by doxygen 1.3.7