00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
#include "precomp.h"
00012
#pragma hdrstop
00013
00014
00015
00016
00017 #define LINEBUMP 32
00018
00019
00020
00021
00022 #define ML_REFRESH 0xffffffff
00023
00024 __inline
void MLSanityCheck(
PED ped)
00025 {
00026 UNREFERENCED_PARAMETER(ped);
00027
00028 UserAssert(ped->
cch >= ped->
chLines[ped->
cLines - 1]);
00029 }
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 UINT MLGetLineWidth(HDC hdc, LPSTR lpstr,
int nCnt,
PED ped)
00041 {
00042
return(
ECTabTheTextOut(hdc, 0, 0, 0, 0, lpstr, nCnt, 0, ped, 0,
ECT_CALC,
NULL));
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 void MLSize(
PED ped, BOOL fRedraw)
00057 {
00058
00059 ped->
ichLinesOnScreen = (ped->
rcFmt.bottom - ped->
rcFmt.top) / ped->
lineHeight;
00060
00061
00062 ped->
rcFmt.bottom = ped->
rcFmt.top + ped->
ichLinesOnScreen * ped->
lineHeight;
00063
00064
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 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 int MLCalcXOffset(
00086
PED ped,
00087 HDC hdc,
00088
int lineNumber)
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
00112
00113
00114
00115
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
00126
00127
00128
return max(0, (
int)(lineWidth-1));
00129 }
00130
00131
return 0;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 ICH MLMoveSelection(
00145
PED ped,
00146 ICH ich,
00147 BOOL fLeft)
00148 {
00149
00150
if (fLeft && ich > 0) {
00151
00152
00153
00154
00155 ich =
ECPrevIch( ped,
NULL, ich );
00156
if (ich) {
00157
if (ped->
fAnsi) {
00158 LPSTR pText;
00159
00160
00161
00162
00163 pText =
ECLock(ped) + ich;
00164
00165
00166
00167
00168
if (*(WORD UNALIGNED *)(pText - 1) == 0x0A0D) {
00169 ich--;
00170
if (ich && *(pText - 2) == 0x0D)
00171 ich--;
00172 }
00173
ECUnlock(ped);
00174 }
else {
00175 LPWSTR pwText;
00176
00177
00178
00179
00180 pwText = (LPWSTR)
ECLock(ped) + ich;
00181
00182
00183
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
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
00205
00206
if (*(WORD UNALIGNED *)(pText - 1) == 0x0A0D)
00207 ich++;
00208
else {
00209
00210
00211
00212
00213
if (ich && *(WORD UNALIGNED *)pText == 0x0A0D && *(pText - 1) == 0x0D)
00214 ich += 2;
00215 }
00216
ECUnlock(ped);
00217 }
else {
00218 LPWSTR pwText;
00219 pwText = (LPWSTR)
ECLock(ped) + ich;
00220
00221
00222
00223
00224
if (*(pwText - 1) == 0x0D && *pwText == 0x0A)
00225 ich++;
00226
else {
00227
00228
00229
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 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 ICH MLMoveSelectionRestricted(
00265
PED ped,
00266 ICH ich,
00267 BOOL fLeft)
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 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 void MLSetCaretPosition(
00293
PED ped,
00294 HDC hdc)
00295 {
00296 POINT position;
00297
BOOL prevLine;
00298
int x = -20000;
00299
int y = -20000;
00300
00301
00302
00303
00304
00305
if (!ped->
fFocus || !
_IsWindowVisible(ped->
pwnd))
00306
return;
00307
00308
00309
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
00342
00343
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
00358
if (
fpImmIsIME(
THREAD_HKL())) {
00359
if (x != -20000 && y != -20000) {
00360
ECImmSetCompositionWindow(ped, x, y);
00361 }
00362 }
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 ICH MLLine(
00375
PED ped,
00376 ICH lineNumber)
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
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
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
00408
00409 result--;
00410 }
00411 }
else {
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
00421
00422 result--;
00423 }
00424
00425 }
00426
ECUnlock(ped);
00427 }
00428 }
00429
return (result);
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 int MLIchToLine(
00444
PED ped,
00445 ICH ich)
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 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 INT MLIchToYPos(
00503
PED ped,
00504 ICH ich,
00505 BOOL prevLine)
00506 {
00507
int iline;
00508
int yPosition;
00509 PSTR pText;
00510
00511
00512
00513
00514 iline =
MLIchToLine(ped, ich);
00515
00516
00517
00518
00519
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
00530
00531
00532 iline--;
00533
00534 yPosition = yPosition - ped->
lineHeight;
00535 }
00536
ECUnlock(ped);
00537
00538
return yPosition;
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 void MLIchToXYPos(
00554
PED ped,
00555 HDC hdc,
00556 ICH ich,
00557 BOOL prevLine,
00558 LPPOINT ppt)
00559 {
00560
int iline;
00561
ICH cch;
00562
int xPosition, yPosition;
00563
int xOffset;
00564
00565
00566
00567
00568
00569 PSTR pText, pTextStart, pLineStart;
00570
00571
00572
00573
00574 iline =
MLIchToLine(ped, ich);
00575
00576
00577
00578
00579
00580
00581 yPosition = (iline - ped->
ichScreenStart) * ped->
lineHeight + ped->
rcFmt.top;
00582
00583
00584
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
00594
00595
00596 iline--;
00597
00598 yPosition = yPosition - ped->
lineHeight;
00599 pLineStart = pTextStart + ped->
chLines[iline] * ped->
cbChar;
00600
00601
00602
00603
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
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
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
00654
00655
if (ped->
pLpkEditCallout) {
00656
00657
00658
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 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 ICH MLMouseToIch(
00690
PED ped,
00691 HDC hdc,
00692 LPPOINT mousePt,
00693 LPICH pline)
00694 {
00695
int xOffset;
00696 LPSTR pLineStart;
00697
int height = mousePt->y;
00698
int line;
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
00712
00713 line = ped->
ichScreenStart;
00714
if (height <= ped->
rcFmt.top) {
00715
00716
00717
00718
00719
00720
00721 line =
max(0, line-1);
00722 }
else if (height >= ped->
rcFmt.bottom) {
00723
00724
00725
00726
00727 line =
min(line+(
int)ped->
ichLinesOnScreen, (
int)(ped->
cLines-1));
00728 }
else {
00729
00730
00731
00732
00733 line =
min(line + (
int)((height - ped->
rcFmt.top) / ped->
lineHeight),
00734 (
int)(ped->
cLines - 1));
00735 }
00736
00737
00738
00739
00740 pLineStart =
ECLock(ped) + ped->
chLines[line] * ped->
cbChar;
00741 cLineLength =
MLLine(ped, line);
00742 RIPMSG3(RIP_VERBOSE,
"MLLine(ped=%x, line=%d) returned %d\n", ped, line, cLineLength);
00743 UserAssert((
int)cLineLength >= 0);
00744
00745
00746
00747
00748
00749
if (ped->
pLpkEditCallout) {
00750
00751
00752
00753 cch = ped->
chLines[line] + ped->
pLpkEditCallout->
EditMouseToIch
00754 (ped, hdc, pLineStart, cLineLength, width);
00755 }
else {
00756
00757
00758
00759
00760
00761
00762
if (ped->
format != ES_LEFT) {
00763 xOffset =
MLCalcXOffset(ped, hdc, line);
00764 }
else {
00765
00766
00767
00768
00769 xOffset = 0;
00770 }
00771
00772 width = width - xOffset;
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
if (width >= ped->
rcFmt.right) {
00783
00784
00785
00786
00787 cch =
ECCchInWidth(ped, hdc, pLineStart, cLineLength,
00788 ped->
rcFmt.right - ped->
rcFmt.left + ped->
xOffset,
TRUE);
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
if (ped->
fAnsi && ped->
fDBCS) {
00799
ICH cch2 =
min(cch+1,cLineLength);
00800
if (
ECAdjustIch(ped, pLineStart, cch2) != cch2) {
00801
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
00814
00815
00816
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
00835
00836 lastHighWidth =
MLGetLineWidth(hdc, pLineStart, cLineLength, ped);
00837
if (lastHighWidth <= iCurWidth) {
00838 cLineLengthNew = cLineLength;
00839
goto edAdjust;
00840 }
00841
00842
00843
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
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
00875
00876
00877
00878
if (cLineLengthLow == cLineLengthNew) {
00879
00880
00881
00882
if ((lastHighWidth - iCurWidth) < (iCurWidth - textWidth)) {
00883 cLineLengthNew++;
00884 }
00885 }
else {
00886
00887
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 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 void MLChangeSelection(
00920
PED ped,
00921 HDC hdc,
00922 ICH ichNewMinSel,
00923 ICH ichNewMaxSel)
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
00939
00940 ichOldMinSel = ped->
ichMinSel;
00941 ichOldMaxSel = ped->
ichMaxSel;
00942
00943
00944
00945
00946 ped->
ichMinSel = ichNewMinSel;
00947 ped->
ichMaxSel = ichNewMaxSel;
00948
00949
00950
00951
00952
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
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
00981
00982
MLSetCaretPosition(ped, hdc);
00983
00984
if (ped->
fFocus) {
00985
NtUserShowCaret(ped->
hwnd);
00986 }
00987
00988 }
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 void MLUpdateiCaretLine(
PED ped)
01004 {
01005 PSTR pText;
01006
01007 ped->
iCaretLine =
MLIchToLine(ped, ped->
ichCaret);
01008
01009
01010
01011
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 }
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 ICH MLInsertText(
01041
PED ped,
01042 LPSTR lpText,
01043 ICH cchInsert,
01044 BOOL fUserTyping)
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
01070
01071
01072
ECNotifyParent(ped,EN_MAXTEXT);
01073
return 0;
01074 }
01075
01076
01077
01078
01079 validCch =
min(validCch, ped->
cchTextMax - ped->
cch);
01080
01081
01082
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
01096
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
01114
01115
ECSaveUndo(
Pundo(ped), (
PUNDO)&undo, !ped->
fAutoVScroll);
01116
01117 hdc =
ECGetEditDC(ped,
FALSE);
01118
01119
01120
01121
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
01131
01132 validCchTemp = validCch;
01133
if (!
ECInsertText(ped, lpText, &validCchTemp)) {
01134
01135
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
01148
01149
01150
01151 RIPMSG2(RIP_WARNING,
"MLInsertText: validCch is changed (%x -> %x) in ECInsertText.",
01152 validCch, validCchTemp);
01153 }
01154
#endif
01155
01156
01157
01158
01159
MLBuildchLines(ped, (
ICH)oldCaretLine, (
int)validCch, fCRLF?(
BOOL)FALSE:fUserTyping, &ll, &hl);
01160
01161
if (ped->
cch)
01162
01163
01164
01165
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
01180
01181
if (ped->
wLeftMargin) {
01182
if (!( ped->
format == ES_LEFT
01183 && ( (!ped->
fRtoLReading && ped->
xOffset > 0)
01184 || ( ped->
fRtoLReading && xFarOffset < ped->
maxPixelWidth)))) {
01185 rc.left -= ped->
wLeftMargin;
01186 }
01187 }
01188
01189
01190
if (ped->
wRightMargin) {
01191
if (!( ped->
format == ES_LEFT
01192 && ( ( ped->
fRtoLReading && ped->
xOffset > 0)
01193 || (!ped->
fRtoLReading && xFarOffset < ped->
maxPixelWidth)))) {
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
01213
01214
01215
ECNotifyParent(ped,EN_MAXTEXT);
01216
return (0);
01217 }
else {
01218
ECEmptyUndo(&undo);
01219 }
01220 }
01221
01222
if (fUserTyping && ped->
fWrap) {
01223
01224
01225
01226
01227
01228
01229
01230
if (ped->
fDBCS && ped->
fAnsi) {
01231 oldCaret =
ECAdjustIch(ped,
01232
ECLock(ped),
01233
min((
ICH)LOWORD(ll),oldCaret));
01234
01235 }
else {
01236 oldCaret =
min((
ICH)LOWORD(ll), oldCaret);
01237 }
01238 }
01239
01240
01241
MLUpdateiCaretLine(ped);
01242
01243
ECNotifyParent(ped, EN_UPDATE);
01244
01245
01246
01247
01248
if (!
IsWindow(hwndSave))
01249
return 0;
01250
01251
if (
_IsWindowVisible(ped->
pwnd)) {
01252
01253
01254
01255
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
01264
if (fCRLF || !fUserTyping) {
01265
01266
01267
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
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
01294
01295
if (!
IsWindow(hwndSave))
01296
return 0;
01297
else
01298
return validCch;
01299 }
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309 void MLReplaceSel(
PED ped, LPSTR lpText)
01310 {
01311
ICH cchText;
01312
01313
01314
01315
01316
ECEmptyUndo(
Pundo(ped));
01317
MLDeleteText(ped);
01318
01319
01320
01321
01322
01323
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
01337
01338
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
01350
01351
ECSaveUndo((
PUNDO)&undo,
Pundo(ped),
FALSE);
01352
MLUndo(ped);
01353 }
01354 }
01355 }
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 ICH MLDeleteText(
01368
PED ped)
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
01384
01385
01386 minSelLine =
MLIchToLine(ped, minSel);
01387 maxSelLine =
MLIchToLine(ped, maxSel);
01388
01389
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
01411
01412
01413
if (fFastDelete) {
01414
01415
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
01431
01432 hdc =
ECGetEditDC(ped,
FALSE);
01433
01434
01435
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
01449
01450
01451
01452
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 }
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487 BOOL MLInsertchLine(
01488
PED ped,
01489 ICH iLine,
01490 ICH ich,
01491 BOOL fUserTyping)
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
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
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 }
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538 void MLShiftchLines(
01539
PED ped,
01540 ICH iLine,
01541
int delta)
01542 {
01543
if (iLine >= ped->
cLines)
01544
return;
01545
01546
01547
01548
01549
for (; iLine < ped->
cLines; iLine++)
01550 ped->
chLines[iLine] += delta;
01551 }
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562 void MLBuildchLines(
01563
PED ped,
01564 ICH iLine,
01565
int cchDelta,
01566 BOOL fUserTyping,
01567 PLONG pll,
01568 PLONG phl)
01569 {
01570 PSTR ptext;
01571
01572
01573
01574
01575
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;
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
01613
01614
01615 ped->
maxPixelWidth = 0;
01616
01617
01618
01619
01620
01621 ped->
cLines = 1;
01622 }
01623
01624
01625
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
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
01669
01670
01671
01672
01673
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
01686
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
01703
01704
01705
if(ped->
rcFmt.right > ped->
rcFmt.left) {
01706
01707
01708
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
01741
01742
01743
01744
01745 ichLineEnd =
ECNextIch(ped,
NULL, ichLineEnd);
01746 }
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
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
01766
01767
01768
01769
01770
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 {
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
01805
01806
01807
01808
01809
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
01826
01827
if (ichLineEnd < ped->
cch) {
01828 ichLineEnd++;
01829 }
01830 }
01831
01832
01833
01834
01835
01836 ichLineEndBeforeCRLF = ichLineEnd;
01837
01838
if (ped->
fAnsi) {
01839
if (ichLineEnd < ped->
cch && *(ptext + ichLineEnd) == 0x0D)
01840 ichLineEnd += 2;
01841
01842
01843
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
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
01864
01865
01866 iLine++;
01867
01868
if (!fUserTyping || (iLine > ped->
cLines - 1) || (ped->
chLines[iLine] != ichLineEnd)) {
01869
01870
01871
01872
01873
if (!fLineBroken) {
01874
01875
01876
01877
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
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
01901
01902
goto UnlockAndEndUp;
01903 }
01904
01905 ichLineStart = ichLineEnd;
01906 }
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
01917
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
01924
01925
if (!fLineBroken) {
01926
01927
01928
01929
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 }
01957
01958
01959
01960
01961
01962
01963
01964
01965 void MLPaint(
PED ped, HDC hdc, LPRECT lprc)
01966 {
01967 HFONT hOldFont;
01968
ICH imin;
01969
ICH imax;
01970
01971
01972
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
01994 imin = 0;
01995 imax = ped->
cch;
01996 }
else {
01997
01998 imin = (
ICH)
MLMouseToIch(ped, hdc, ((LPPOINT) &lprc->left),
NULL) - 1;
01999
if (imin == -1)
02000 imin = 0;
02001
02002
02003
02004
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 }
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028 void MLKeyDown(
02029
PED ped,
02030 UINT virtKeyCode,
02031
int keyMods)
02032 {
02033 HDC hdc;
02034
BOOL prevLine;
02035 POINT mousePt;
02036
int defaultDlgId;
02037
int iScrollAmt;
02038
02039
02040
02041
02042
02043
02044
02045
02046
ICH newMaxSel = ped->
ichMaxSel;
02047
ICH newMinSel = ped->
ichMinSel;
02048
02049
02050
02051
02052
BOOL changeSelection =
FALSE;
02053
02054
02055
02056
02057
BOOL MinEqMax = (newMaxSel == newMinSel);
02058
BOOL MinEqCar = (ped->
ichCaret == newMinSel);
02059
BOOL MaxEqCar = (ped->
ichCaret == newMaxSel);
02060
02061
02062
02063
02064
int scState;
02065
02066
if (ped->
fMouseDown) {
02067
02068
02069
02070
02071
return ;
02072 }
02073
02074 scState =
ECGetModKeys(keyMods);
02075
02076
switch (virtKeyCode) {
02077
case VK_ESCAPE:
02078
if (ped->
fInDialogBox) {
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
#if 0
02089
if (
GetDlgItem(ped->
hwndParent, IDCANCEL))
02090
#endif
02091
02092
02093
02094
02095
02096
PostMessage(ped->
hwndParent, WM_CLOSE, 0, 0
L);
02097 }
02098
return ;
02099
02100
case VK_RETURN:
02101
if (ped->
fInDialogBox) {
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
if (scState !=
CTRLDOWN) {
02112
02113
if (
TestWF(ped->
pwnd,
EFWANTRETURN)) {
02114
02115
02116
02117
02118
02119
return ;
02120 }
02121
02122 defaultDlgId = (
int)(
DWORD)LOWORD(
SendMessage(ped->
hwndParent,
02123 DM_GETDEFID, 0, 0
L));
02124
if (defaultDlgId) {
02125 HWND hwnd =
GetDlgItem(ped->
hwndParent, defaultDlgId);
02126
if (hwnd) {
02127
SendMessage(ped->
hwndParent, WM_NEXTDLGCTL, (WPARAM)hwnd, 1
L);
02128
if (!ped->
fFocus)
02129
PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0
L);
02130 }
02131 }
02132 }
02133
02134
return ;
02135 }
02136
break;
02137
02138
case VK_TAB:
02139
02140
02141
02142
02143
02144
02145
02146
if (scState ==
CTRLDOWN)
02147
MLChar(ped, virtKeyCode, keyMods);
02148
else if (ped->
fInDialogBox)
02149
SendMessage(ped->
hwndParent, WM_NEXTDLGCTL, scState ==
SHFTDOWN, 0
L);
02150
02151
return ;
02152
02153
case VK_LEFT:
02154
02155
02156
02157
if (ped->
ichCaret) {
02158
02159
if (scState &
CTRLDOWN) {
02160
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
02167 ped->
ichCaret =
MLMoveSelection(ped, ped->
ichCaret,
TRUE);
02168 }
02169 }
02170
02171
02172
if (scState &
SHFTDOWN) {
02173
if (MaxEqCar && !MinEqMax) {
02174
02175 newMaxSel = ped->
ichCaret;
02176
02177 UserAssert(newMinSel == ped->
ichMinSel);
02178 }
else {
02179
02180 newMinSel = ped->
ichCaret;
02181 }
02182 }
else {
02183
02184 newMaxSel = newMinSel = ped->
ichCaret;
02185 }
02186
02187 changeSelection =
TRUE;
02188 }
else {
02189
02190
02191
02192
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
02205
02206
if (ped->
ichCaret < ped->
cch) {
02207
02208
02209
02210
if (scState &
CTRLDOWN) {
02211
02212
ECWord(ped, ped->
ichCaret,
FALSE,
NULL, &ped->
ichCaret);
02213 }
else {
02214
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
02224
02225
if (scState &
SHFTDOWN) {
02226
if (MinEqCar && !MinEqMax) {
02227
02228 newMinSel = ped->
ichCaret;
02229
02230 UserAssert(newMaxSel == ped->
ichMaxSel);
02231 }
else {
02232
02233 newMaxSel = ped->
ichCaret;
02234 }
02235 }
else {
02236
02237 newMaxSel = newMinSel = ped->
ichCaret;
02238 }
02239
02240 changeSelection =
TRUE;
02241 }
else {
02242
02243
02244
02245
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
02271
02272
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
02284
02285
if (scState &
CTRLDOWN) {
02286
02287 ped->
ichCaret = 0;
02288 }
else {
02289
02290 ped->
ichCaret = ped->
chLines[ped->
iCaretLine];
02291 }
02292
02293
02294
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
02309 newMaxSel = ped->
ichCaret;
02310 }
02311
02312 changeSelection =
TRUE;
02313
break;
02314
02315
case VK_END:
02316
02317
02318
02319
if (scState &
CTRLDOWN) {
02320
02321 ped->
ichCaret = ped->
cch;
02322 }
else {
02323
02324 ped->
ichCaret = ped->
chLines[ped->
iCaretLine] +
02325
MLLine(ped, ped->
iCaretLine);
02326 }
02327
02328
02329 newMaxSel = ped->
ichCaret;
02330
02331
if (scState &
SHFTDOWN) {
02332
if (MinEqCar && !MinEqMax) {
02333
02334
if (scState &
CTRLDOWN) {
02335 newMinSel = ped->
ichMaxSel;
02336 }
else {
02337 newMinSel = ped->
ichCaret;
02338 newMaxSel = ped->
ichMaxSel;
02339 }
02340 }
02341 }
else {
02342
02343 newMinSel = ped->
ichCaret;
02344 }
02345
02346 changeSelection =
TRUE;
02347
break;
02348
02349
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
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, 0
L);
02370
02371
02372
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
02380
02381 iScrollAmt = ((ped->
rcFmt.right - ped->
rcFmt.left) / ped->
aveCharWidth) - 1;
02382
if (virtKeyCode == VK_PRIOR)
02383 iScrollAmt *= -1;
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
02399
02400
02401
if ((ped->
ichMaxSel < ped->
cch) && (ped->
ichMinSel == ped->
ichMaxSel)) {
02402
02403
02404
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
02422
02423
02424
if (ped->
ichMinSel == ped->
ichMaxSel) {
02425
goto DeleteAnotherChar;
02426 }
else {
02427
SendMessage(ped->
hwnd, WM_CUT, (
UINT)0, 0
L);
02428 }
02429
02430
break;
02431
02432
case CTRLDOWN:
02433
02434
02435
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
02456
02457
02458
break;
02459
02460
case VK_INSERT:
02461
if (scState ==
CTRLDOWN || scState ==
SHFTDOWN) {
02462
02463
02464
02465
02466
02467
02468
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
02481
02482 ped->
iCaretLine =
MLIchToLine(ped, ped->
ichCaret);
02483
02484
if (virtKeyCode == VK_END &&
02485
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
02493
02494
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
02512
02513
MLSetCaretPosition(ped, hdc);
02514
ECReleaseEditDC(ped, hdc,
FALSE);
02515
02516
02517
02518
02519
MLEnsureCaretVisible(ped);
02520 }
02521 }
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531 void MLChar(
02532
PED ped,
02533 DWORD keyValue,
02534
int keyMods)
02535 {
02536 WCHAR keyPress;
02537
BOOL updateText =
FALSE;
02538
02539
02540
02541
02542
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
02553
02554
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
02569
02570
02571
02572
02573
02574
02575
02576
if (keyPress == VK_TAB ||
02577 (keyPress == VK_RETURN && !
TestWF(ped->
pwnd,
EFWANTRETURN)))
02578
return ;
02579 }
02580
02581
02582
02583
02584
02585
if ((ped->
fReadOnly) && !((keyPress == 3) && (scState ==
CTRLDOWN))) {
02586
return ;
02587 }
02588 }
02589
02590
switch (keyPress) {
02591
case 0x0A:
02592 keyPress = VK_RETURN;
02593
02594
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
02609
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
02624
02625
switch(keyPress) {
02626
UINT msg;
02627
02628
02629
case 26:
02630
msg = WM_UNDO;
02631
goto SendEditingMessage;
02632
break;
02633
02634
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
02646
case 3:
02647
msg = WM_COPY;
02648
goto SendEditingMessage;
02649
break;
02650
02651
02652
case 22:
02653
msg = WM_PASTE;
02654 SendEditingMessage:
02655
SendMessage(ped->
hwnd,
msg, 0, 0
L);
02656
break;
02657
02658
case VK_BACK:
02659
02660
02661
02662
if (!updateText && ped->
ichMinSel)
02663 {
02664
02665
02666
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
02684 || keyPress == 0x1F
02685 ) {
02686
02687
NtUserCallNoParam(SFI_ZZZHIDECURSORNOCAPTURE);
02688
if (ped->
fAnsi) {
02689
02690
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 }
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720 ICH PASCAL NEAR
MLPasteText(
02721
PED ped)
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
02733
02734
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
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
02764
02765
if (ped->
fAnsi)
02766 cchAdded =
strlen(lpchClip);
02767
else
02768 cchAdded = wcslen((LPWSTR)lpchClip);
02769
02770
02771
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 }
02785
02786
02787
02788
02789
02790
02791
02792 void MLMouseMotion(
02793
PED ped,
02794 UINT message,
02795 UINT virtKeyDown,
02796 LPPOINT mousePt)
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
02814
02815 ped->
ptPrevMouse = *mousePt;
02816 ped->
prevKeys = virtKeyDown;
02817
02818
switch (message) {
02819
case WM_LBUTTONDBLCLK:
02820
02821
02822
02823
02824
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
02838
02839 ichMinSel = ll;
02840 ichMaxSel = ped->
ichCaret = lh;
02841 }
else {
02842
02843
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
02863
02864
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
02875
if (ped->
ichStartMinSel || ped->
ichStartMaxSel) {
02876
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
02889 ichMinSel = ped->
ichCaret = mouseCch;
02890
else
02891
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
02903
02904 ichMinSel = ichMaxSel = ped->
ichCaret = mouseCch;
02905 }
else {
02906
02907
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
02925
02926
NtUserSetSystemTimer(ped->
hwnd,
IDSYS_SCROLL,
gpsi->dtScroll,
NULL);
02927
break;
02928
02929
case WM_LBUTTONUP:
02930
if (ped->
fMouseDown) {
02931
02932
02933
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
02955
02956
NtUserSetFocus(ped->
hwnd);
02957 }
02958 }
02959
02960
02961
02962
02963
02964
02965
02966 LONG
MLScroll(
02967
PED ped,
02968 BOOL fVertical,
02969
int cmd,
02970
int iAmt,
02971 BOOL fRedraw)
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
02991
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
03013
03014
03015
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:
03032 newPos = 0;
03033
break;
03034
03035
case SB_BOTTOM:
03036
if (fVertical)
03037 newPos = ped->
cLines;
03038
else
03039 newPos = ped->
maxPixelWidth;
03040
break;
03041
03042
case SB_PAGEUP:
03043 fUp =
TRUE;
03044
case SB_PAGEDOWN:
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:
03059 fUp =
TRUE;
03060
case SB_LINEDOWN:
03061
03062 dwTime = iAmt;
03063
03064 iAmt = 1;
03065
03066
if (fUp)
03067 iAmt = -iAmt;
03068
03069
03070
03071
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(0
L);
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
03111
03112
03113
int iMaxPos;
03114
03115
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(0
L);
03127
03128
if (ped->
pLpkEditCallout && ped->
fRtoLReading && !fVertical
03129 && ped->
maxPixelWidth > ped->
rcFmt.right - ped->
rcFmt.left) {
03130
03131 newPos = ped->
maxPixelWidth
03132 - (newPos + ped->
rcFmt.right - ped->
rcFmt.left);
03133 oldPos = -oldPos;
03134
if (newPos<0) {
03135
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
03151
03152
03153
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) {
03166 rcClipRect.left -= ped->
wLeftMargin;
03167 rcClipRect.right += ped->
wRightMargin;
03168 }
03169
03170
IntersectRect(&rc, &rc, &rcClipRect);
03171 rc.bottom++;
03172
03173
03174
03175
03176
03177
03178
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
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
03200
03201
if (ped->
wLeftMargin) {
03202 rc.left = ped->
rcFmt.left - ped->
wLeftMargin;
03203 rc.right = ped->
rcFmt.left;
03204
if ( (ped->
format != ES_LEFT)
03205 ||
03206 (!ped->
fRtoLReading && ped->
xOffset == 0)
03207 ||
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, 0
L);
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)
03220 ||
03221 (ped->
fRtoLReading && ped->
xOffset == 0)
03222 ||
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, 0
L);
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
03239
if (ped->
wLeftMargin && !fVertical) {
03240
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, 0
L);
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 }
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274 void MLSetFocus(
03275
PED ped)
03276 {
03277 HDC hdc;
03278
03279
if (!ped->
fFocus) {
03280 ped->
fFocus = 1;
03281
03282 hdc =
ECGetEditDC(ped,
TRUE);
03283
03284
03285
03286
03287
03288
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
03301
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
03316
03317
ECNotifyParent(ped, EN_SETFOCUS);
03318 }
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329 void MLKillFocus(
03330
PED ped)
03331 {
03332 HDC hdc;
03333
03334
03335
03336
03337
gcWheelDelta = 0;
03338
03339
if (ped->
fFocus) {
03340 ped->
fFocus = 0;
03341
03342
03343
03344
03345
03346
03347
03348
03349
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
03360
03361
NtUserDestroyCaret();
03362 }
03363
03364
03365
03366
03367
ECNotifyParent(ped, EN_KILLFOCUS);
03368 }
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379 BOOL MLEnsureCaretVisible(
03380
PED ped)
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
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
03420
03421
03422
03423 iFmtWidth /= 3;
03424
if (fHScroll = (xposition < ped->
rcFmt.left))
03425
03426 iAmt = ped->
rcFmt.left + iFmtWidth;
03427
else if (fHScroll = (xposition > ped->
rcFmt.right))
03428
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 }
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457 LRESULT
MLEditWndProc(
03458 HWND hwnd,
03459
PED ped,
03460 UINT message,
03461 WPARAM wParam,
03462 LPARAM lParam)
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 1
L;
03494
03495
case GWL_EXSTYLE:
03496
ECUpdateFormat(ped,
03497 GetWindowLong(ped->
hwnd, GWL_STYLE),
03498 ((LPSTYLESTRUCT)lParam)->styleNew);
03499
return 1
L;
03500 }
03501 }
03502
03503
goto PassToDefaultWindowProc;
03504
03505
case WM_CHAR:
03506
03507
03508
03509
03510
03511
MLChar(ped, (
UINT)wParam, 0);
03512
break;
03513
03514
case WM_ERASEBKGND: {
03515 HBRUSH hbr;
03516
03517
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
03533
03534
03535
03536
03537
03538
03539
03540
03541
if (lParam)
03542 ped->
fInDialogBox =
TRUE;
03543
03544
03545
03546
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
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
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
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
03610
03611
03612
MLKeyDown(ped, (
UINT)wParam, 0);
03613
break;
03614
03615
case WM_KILLFOCUS:
03616
03617
03618
03619
03620
03621
MLKillFocus(ped);
03622
break;
03623
03624
case WM_CAPTURECHANGED:
03625
03626
03627
03628
03629
if (ped->
fMouseDown) {
03630
03631
03632
03633
03634
03635
03636
03637
03638 ped->
fMouseDown =
FALSE;
03639
NtUserKillSystemTimer(ped->
hwnd,
IDSYS_SCROLL);
03640 }
03641
break;
03642
03643
case WM_SYSTIMER:
03644
03645
03646
03647
03648
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
03663
03664
case WM_LBUTTONDBLCLK:
03665
case WM_LBUTTONDOWN:
03666
case WM_LBUTTONUP:
03667
03668
03669
03670
03671 POINTSTOPOINT(pt, lParam);
03672
MLMouseMotion(ped, message, (
UINT)wParam, &pt);
03673
break;
03674
03675
case WM_CREATE:
03676
03677
03678
03679
03680
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
03691
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
03712
03713
03714
if (!ped->
fReadOnly)
03715
MLPasteText(ped);
03716
break;
03717
03718
case WM_SETFOCUS:
03719
03720
03721
03722
03723
03724
MLSetFocus(ped);
03725
break;
03726
03727
case WM_SIZE:
03728
03729
03730
03731
03732
03733
03734
ECSize(ped,
NULL,
TRUE);
03735
break;
03736
03737
case EM_FMTLINES:
03738
03739
03740
03741
03742
03743
03744
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
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
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
03781
03782
03783
03784
return MLGetLine(ped, (
ICH)wParam, (
ICH)*(WORD UNALIGNED *)lParam, (LPSTR)lParam);
03785
03786
case EM_LINEFROMCHAR:
03787
03788
03789
03790
03791
03792
03793
return (LRESULT)
MLIchToLine(ped, (
ICH)wParam);
03794
03795
case EM_LINEINDEX:
03796
03797
03798
03799
03800
03801
03802
03803
03804
return (LRESULT)
MLLineIndex(ped, (
ICH)wParam);
03805
03806
case EM_LINELENGTH:
03807
03808
03809
03810
03811
03812
03813
03814
03815
return (LRESULT)
MLLineLength(ped, (
ICH)wParam);
03816
03817
case EM_LINESCROLL:
03818
03819
03820
03821
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
03831
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
03842
03843
03844
MLSetHandle(ped, (HANDLE)wParam);
03845
break;
03846
03847
case EM_SETRECT:
03848
case EM_SETRECTNP:
03849
03850
03851
03852
03853
03854
ECSize(ped, (LPRECT) lParam, (message != EM_SETRECTNP));
03855
break;
03856
03857
case EM_SETSEL:
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
MLSetSelection(ped,
TRUE, (
ICH)wParam, (
ICH)lParam);
03870
break;
03871
03872
case EM_SCROLLCARET:
03873
03874
03875
03876
03877
MLEnsureCaretVisible(ped);
03878
break;
03879
03880
case EM_GETFIRSTVISIBLELINE:
03881
03882
03883
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, 0
L);
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
03902
03903
03904
03905
return MLSetTabStops(ped, (
int)wParam, (LPINT)lParam);
03906
03907
case EM_POSFROMCHAR:
03908
03909
03910
03911
03912
03913
case EM_CHARFROMPOS:
03914
03915
03916
03917
03918
03919
03920
03921
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
03949
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 1
L;
03967 }
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991 void MLDrawText(
03992
PED ped,
03993 HDC hdc,
03994 ICH ichStart,
03995 ICH ichEnd,
03996 BOOL fSelChange)
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
04021
if (!ped->
ichLinesOnScreen)
04022
return;
04023
04024
ECGetBrush(ped, hdc);
04025
04026
04027
04028
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
04037
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);
04043 wEndLine =
MLIchToLine(ped, ichEnd);
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
04052
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
04067
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
04079
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
04089
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
04098
04099
04100
04101
04102
MLIchToXYPos(ped, hdc, ichStart,
FALSE, &pt);
04103 xClipStPos = xStPos = pt.x;
04104 yPos = pt.y;
04105
04106
04107 ichAttrib = ichStart;
04108
04109
04110
04111
04112
04113
04114
if (fFirstLineOfBlock && ped->
wMaxNegC) {
04115 fFirstLineOfBlock =
FALSE;
04116 ichNewStart =
max(((
int)(ichStart - ped->
wMaxNegCcharPos)), ((
int)ped->
chLines[wCurLine]));
04117
04118
04119
if (ichNewStart != ichStart) {
04120
if (ped->
fAnsi && ped->
fDBCS) {
04121
04122
04123
04124 ichNewStart =
ECAdjustIchNext( ped, pText, ichNewStart );
04125 }
04126
MLIchToXYPos(ped, hdc, ichStart = ichNewStart,
FALSE, &pt);
04127 xStPos = pt.x;
04128 }
04129 }
04130
04131
04132 iRemainingLengthInLine =
MLLine(ped, wCurLine) -
04133 (ichStart - ped->
chLines[wCurLine]);
04134
04135
04136
04137
if (wCurLine == wEndLine)
04138 LengthToDraw = ichEnd - ichStart;
04139
else
04140 LengthToDraw = iRemainingLengthInLine;
04141
04142
04143
04144
if (ped->
format != ES_LEFT)
04145 xOffset =
MLCalcXOffset(ped, hdc, wCurLine);
04146
else
04147 xOffset = -((
int)(ped->
xOffset));
04148
04149
04150
if (ichAttrib == ped->
chLines[wCurLine]) {
04151 fLineBegins =
TRUE;
04152 xClipStPos = ped->
rcFmt.left - ped->
wLeftMargin;
04153 }
04154
04155
04156
04157
04158
do {
04159
04160
04161
04162
04163
04164
if (iRemainingLengthInLine < 0)
04165
break;
04166
04167
04168
04169
04170
04171
if (!(ped->
ichMinSel == ped->
ichMaxSel ||
04172 ichAttrib >= ped->
ichMaxSel ||
04173 ichEnd < ped->
ichMinSel ||
04174 (!ped->
fNoHideSel && !ped->
fFocus))) {
04175
04176
04177
04178
04179
if (ichAttrib < ped->
ichMinSel) {
04180 fSelected =
FALSE;
04181
04182
04183 CurStripLength =
min(ichStart+LengthToDraw, ped->
ichMinSel)-ichStart;
04184 fLineBegins =
FALSE;
04185 }
else {
04186
04187
if (fLineBegins) {
04188
04189 fSelected =
FALSE;
04190 CurStripLength = 0;
04191 xClipStPos = ped->
rcFmt.left - ped->
wLeftMargin;
04192 fLineBegins =
FALSE;
04193 }
else {
04194
04195 fSelected =
TRUE;
04196 CurStripLength =
min(ichStart+LengthToDraw, ped->
ichMaxSel)-ichStart;
04197
04198
04199 bkColorSave = SetBkColor(hdc,
GetSysColor(COLOR_HIGHLIGHT));
04200
if (!ped->
fDisabled)
04201 textColorSave = SetTextColor(hdc,
GetSysColor(COLOR_HIGHLIGHTTEXT));
04202 }
04203 }
04204 }
else {
04205
04206 CurStripLength = LengthToDraw;
04207 }
04208
04209
04210
04211
04212
04213 fDrawOnSameLine = (LengthToDraw != CurStripLength);
04214
04215
04216
04217
04218
04219
04220 ExtraLengthForNegA =
min(iRemainingLengthInLine-CurStripLength, ped->
wMaxNegAcharPos);
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
if (iRemainingLengthInLine == (
int)CurStripLength) {
04232
if (fSelected) {
04233
04234 fDrawEndOfLineStrip =
TRUE;
04235
MLIchToXYPos(ped, hdc, ichStart+CurStripLength,
TRUE, &pt);
04236 xClipEndPos = pt.x;
04237 }
else {
04238
04239
04240
04241
04242
04243 xClipEndPos =
MAXCLIPENDPOS;
04244 }
04245 }
else {
04246
04247
04248
04249
04250
MLIchToXYPos(ped, hdc, ichStart+CurStripLength,
FALSE, &pt);
04251 xClipEndPos = pt.x;
04252 }
04253
04254
04255
04256
04257
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
04267
04268
04269 fSelected =
FALSE;
04270 SetBkColor(hdc, bkColorSave);
04271
if (!ped->
fDisabled)
04272 SetTextColor(hdc, textColorSave);
04273 }
04274
04275
04276
if (fDrawOnSameLine || fDrawEndOfLineStrip) {
04277
int iLastDrawnLength;
04278
04279
04280
04281
04282 ichAttrib = ichStart + CurStripLength;
04283
04284
04285
04286
04287
04288
04289 iLastDrawnLength = CurStripLength +ExtraLengthForNegA - NegCInfo.
nCount;
04290
04291
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
04305
04306 xStPos = NegCInfo.
XStartPos;
04307 xClipStPos = xClipEndPos;
04308 }
04309
04310
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);
04320 }
04321
04322
04323 wCurLine++;
04324
if (ped->
cLines > wCurLine)
04325 ichStart = ped->
chLines[wCurLine];
04326
else
04327 ichStart = ichEnd+1;
04328 }
04329
04330
ECUnlock(ped);
04331
04332
NtUserShowCaret(ped->
hwnd);
04333
MLSetCaretPosition(ped, hdc);
04334 }