00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017 LOOKASIDE EditLookaside;
00018
00019
ICH ECFindTabA(LPSTR lpstr, ICH cch);
00020
ICH ECFindTabW(LPWSTR lpstr, ICH cch);
00021
00022 #define umin(a, b) ((unsigned)(a) < (unsigned)(b) ? (unsigned)(a) : (unsigned)(b))
00023 #define umax(a, b) ((unsigned)(a) > (unsigned)(b) ? (unsigned)(a) : (unsigned)(b))
00024
00025 #define UNICODE_CARRIAGERETURN ((WCHAR)0x0d)
00026 #define UNICODE_LINEFEED ((WCHAR)0x0a)
00027 #define UNICODE_TAB ((WCHAR)0x09)
00028
00029
00030
00031 #define ID_IMEOPENCLOSE 10001
00032 #define ID_SOFTKBDOPENCLOSE 10002
00033 #define ID_RECONVERTSTRING 10003
00034
00035 typedef struct {
00036 DWORD fDisableCut : 1;
00037 DWORD fDisablePaste : 1;
00038 DWORD fNeedSeparatorBeforeImeMenu : 1;
00039 DWORD fIME : 1;
00040 }
EditMenuItemState;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 PSTR
ECLock(
00053
PED ped)
00054 {
00055 PSTR ptext =
LOCALLOCK(ped->
hText, ped->
hInstance);
00056 ped->
iLockLevel++;
00057
00058
00059
00060
00061
00062
00063
if (ped->
iLockLevel == 1 && ped->
fEncoded) {
00064
00065
00066
00067
if (ped->
cch != 0) {
00068 STRING string;
00069 string.Length = string.MaximumLength = (
USHORT)(ped->
cch * ped->
cbChar);
00070 string.Buffer = ptext;
00071
00072
RtlRunDecodeUnicodeString(ped->
seed, (PUNICODE_STRING)&string);
00073
00074 }
00075 ped->
fEncoded =
FALSE;
00076 }
00077
return ptext;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 void ECUnlock(
00087
PED ped)
00088 {
00089
00090
00091
00092
00093
00094
if (ped->
charPasswordChar && ped->
iLockLevel == 1 && ped->
cch != 0) {
00095 UNICODE_STRING string;
00096 string.Length = string.MaximumLength = (
USHORT)(ped->
cch * ped->
cbChar);
00097 string.Buffer =
LOCALLOCK(ped->
hText, ped->
hInstance);
00098
00099
RtlRunEncodeUnicodeString(&(ped->
seed), &string);
00100
00101 ped->
fEncoded =
TRUE;
00102
LOCALUNLOCK(ped->
hText, ped->
hInstance);
00103 }
00104
LOCALUNLOCK(ped->
hText, ped->
hInstance);
00105 ped->
iLockLevel--;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 UINT GetActualNegA(
00118 HDC hdc,
00119
PED ped,
00120
int x,
00121 LPSTR lpstring,
00122 ICH ichString,
00123
int nCount,
00124
LPSTRIPINFO NegAInfo)
00125 {
00126
int iCharCount, i;
00127
int iLeftmostPoint = x;
00128 PABC pABCwidthBuff;
00129
UINT wCharIndex;
00130
int xStartPoint = x;
00131 ABC abc;
00132
00133
00134
00135
00136 NegAInfo->XStartPos = x;
00137 NegAInfo->lpString = lpstring;
00138 NegAInfo->nCount = 0;
00139 NegAInfo->ichString = ichString;
00140
00141
00142
00143
if (!ped->
fTrueType) {
00144
if(!ped->
charOverhang) {
00145
return 0;
00146 }
else {
00147 NegAInfo->nCount =
min(nCount, (
int)ped->
wMaxNegAcharPos);
00148
return ped->
charOverhang;
00149 }
00150 }
00151
00152
00153 iCharCount =
min(nCount, (
int)ped->
wMaxNegAcharPos);
00154
00155
00156
if(!ped->
charWidthBuffer) {
00157
00158 NegAInfo->nCount = iCharCount;
00159
return(iCharCount * ped->
aveCharWidth);
00160 }
00161
00162 pABCwidthBuff = (PABC) ped->
charWidthBuffer;
00163
00164
if (ped->
fAnsi) {
00165
for (i = 0; i < iCharCount; i++) {
00166 wCharIndex = (
UINT)(*((
unsigned char *)lpstring));
00167
if (*lpstring == VK_TAB) {
00168
00169
00170 x++;
00171 }
else {
00172
if ( wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH )
00173 x += pABCwidthBuff[wCharIndex].abcA;
00174
else {
00175 GetCharABCWidthsA(hdc, wCharIndex, wCharIndex, &abc) ;
00176 x += abc.abcA;
00177 }
00178
00179
if (x < iLeftmostPoint)
00180 iLeftmostPoint = x;
00181
if (x < xStartPoint)
00182 NegAInfo->nCount = i+1;
00183
00184
if ( wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH ) {
00185 x += pABCwidthBuff[wCharIndex].abcB + pABCwidthBuff[wCharIndex].abcC;
00186 }
else {
00187 x += abc.abcB + abc.abcC;
00188 }
00189 }
00190
00191 lpstring++;
00192 }
00193 }
else {
00194 LPWSTR lpwstring = (LPWSTR) lpstring ;
00195
00196
for (i = 0; i < iCharCount; i++) {
00197 wCharIndex = *lpwstring ;
00198
if (*lpwstring == VK_TAB) {
00199
00200
00201 x++;
00202 }
else {
00203
if ( wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH )
00204 x += pABCwidthBuff[wCharIndex].abcA;
00205
else {
00206 GetCharABCWidthsW(hdc, wCharIndex, wCharIndex, &abc) ;
00207 x += abc.abcA ;
00208 }
00209
00210
if (x < iLeftmostPoint)
00211 iLeftmostPoint = x;
00212
if (x < xStartPoint)
00213 NegAInfo->nCount = i+1;
00214
00215
if ( wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH )
00216 x += pABCwidthBuff[wCharIndex].abcB +
00217 pABCwidthBuff[wCharIndex].abcC;
00218
else
00219 x += abc.abcB + abc.abcC ;
00220 }
00221
00222 lpwstring++;
00223 }
00224 }
00225
00226
00227
return((
UINT)(xStartPoint - iLeftmostPoint));
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 BOOL ECIsAncestorActive(HWND hwnd)
00243 {
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
while (hwnd) {
00254
PWND pwnd =
ValidateHwnd( hwnd );
00255
00256
00257
00258
00259
00260
if (!
TestWF(pwnd,
WFWIN40COMPAT) || !
TestWF(pwnd,
WFCHILD))
00261 hwnd =
NULL;
00262
else if (
TestWF(pwnd,
WFCPRESENT))
00263
return(
TestWF(pwnd,
WFFRAMEON) != 0);
00264
else
00265 hwnd =
GetParent(hwnd);
00266 }
00267
00268
return(
TRUE);
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278 BOOL ECSetIMEMenu(
00279 HMENU hMenu,
00280 HWND hwnd,
00281
EditMenuItemState state)
00282 {
00283
00284 MENUITEMINFO mii;
00285 HIMC hIMC;
00286 HKL hKL;
00287 HMENU hmenuSub;
00288 WCHAR szRes[32];
00289
int nPrevLastItem;
00290
int nItemsAdded = 0;
00291
00292 UserAssert(
IS_IME_ENABLED() && state.
fIME);
00293
00294 hKL =
THREAD_HKL();
00295
if (!
fpImmIsIME(hKL))
00296
return TRUE;
00297
00298 hIMC =
fpImmGetContext(hwnd);
00299
if (hIMC ==
NULL) {
00300
00301
return FALSE;
00302 }
00303
00304 hmenuSub =
GetSubMenu(hMenu, 0);
00305
00306
if (hmenuSub ==
NULL) {
00307
return FALSE;
00308 }
00309
00310 nPrevLastItem =
GetMenuItemCount(hmenuSub);
00311
00312
if (hIMC) {
00313
if (LOWORD(HandleToUlong(hKL)) != 0x412) {
00314
00315
00316
00317
if (
fpImmGetOpenStatus(hIMC))
00318 LoadString(
hmodUser,
STR_IMECLOSE, szRes,
sizeof(szRes));
00319
else
00320 LoadString(
hmodUser,
STR_IMEOPEN, szRes,
sizeof(szRes));
00321
00322 mii.cbSize =
sizeof(MENUITEMINFO);
00323 mii.fMask = MIIM_STRING | MIIM_ID;
00324 mii.dwTypeData = szRes;
00325 mii.cch = 0xffff;
00326 mii.wID =
ID_IMEOPENCLOSE;
00327
InsertMenuItem(hmenuSub, 0xffff,
TRUE, &mii);
00328 ++nItemsAdded;
00329 }
00330
00331
if (
fpImmGetProperty(hKL, IGP_CONVERSION) & IME_CMODE_SOFTKBD) {
00332
DWORD fdwConversion;
00333
00334
fpImmGetConversionStatus(hIMC, &fdwConversion,
NULL);
00335
00336
if (fdwConversion & IME_CMODE_SOFTKBD)
00337 LoadString(
hmodUser,
STR_SOFTKBDCLOSE, szRes,
sizeof(szRes));
00338
else
00339 LoadString(
hmodUser,
STR_SOFTKBDOPEN, szRes,
sizeof(szRes));
00340
00341 mii.cbSize =
sizeof(MENUITEMINFO);
00342 mii.fMask = MIIM_STRING | MIIM_ID;
00343 mii.dwTypeData = szRes;
00344 mii.cch = 0xffff;
00345 mii.wID =
ID_SOFTKBDOPENCLOSE;
00346
InsertMenuItem(hmenuSub, 0xffff,
TRUE, &mii);
00347 ++nItemsAdded;
00348 }
00349
00350
if (LOWORD(HandleToUlong(hKL)) != 0x412) {
00351
00352
00353
00354
DWORD dwSCS =
fpImmGetProperty(hKL, IGP_SETCOMPSTR);
00355
00356 LoadString(
hmodUser,
STR_RECONVERTSTRING, szRes,
sizeof(szRes));
00357
00358 mii.cbSize =
sizeof(MENUITEMINFO);
00359 mii.fMask = MIIM_STRING | MIIM_ID | MIIM_STATE;
00360 mii.dwTypeData = szRes;
00361 mii.fState = 0;
00362 mii.cch = 0xffff;
00363 mii.wID =
ID_RECONVERTSTRING;
00364
00365
if (state.
fDisableCut ||
00366 !(dwSCS & SCS_CAP_SETRECONVERTSTRING) ||
00367 !(dwSCS & SCS_CAP_MAKEREAD)) {
00368 mii.fState |= MFS_GRAYED;
00369 }
00370
00371
InsertMenuItem(hmenuSub, 0xffff,
TRUE, &mii);
00372 ++nItemsAdded;
00373 }
00374 }
00375
00376
00377
00378
00379
if (state.
fNeedSeparatorBeforeImeMenu && nItemsAdded != 0) {
00380
00381
00382
00383
00384
00385 mii.cbSize =
sizeof(MENUITEMINFO);
00386 mii.fMask = MIIM_FTYPE;
00387 mii.fType = MFT_SEPARATOR;
00388
InsertMenuItem(hmenuSub, nPrevLastItem,
TRUE, &mii);
00389 }
00390
else if (!state.
fNeedSeparatorBeforeImeMenu && nItemsAdded == 0) {
00391
00392
00393
00394 UserVerify(
NtUserDeleteMenu(hmenuSub, nPrevLastItem - 1, MF_BYPOSITION));
00395 }
00396
00397
fpImmReleaseContext(hwnd, hIMC);
00398
00399
return TRUE;
00400 }
00401
00402 void ECInOutReconversionMode(
PED ped, BOOL fIn)
00403 {
00404 UserAssert(fIn ==
TRUE || fIn ==
FALSE);
00405
if (fIn == ped->
fInReconversion) {
00406
return;
00407 }
00408 ped->
fInReconversion = fIn;
00409
if (ped->
fFocus) {
00410 (fIn ?
NtUserHideCaret:
NtUserShowCaret)(ped->
hwnd);
00411 }
00412
00413
return;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423 BOOL NEAR
ECDoIMEMenuCommand(
PED ped,
int cmd, HWND hwnd)
00424 {
00425 HIMC hIMC;
00426
00427
00428
switch (cmd) {
00429
case ID_IMEOPENCLOSE:
00430
case ID_SOFTKBDOPENCLOSE:
00431
case ID_RECONVERTSTRING:
00432
break;
00433
default:
00434
return FALSE;
00435 }
00436
00437
00438 hIMC =
fpImmGetContext(hwnd);
00439
if (hIMC ==
NULL) {
00440
00441
return TRUE;
00442 }
00443
00444
switch (cmd) {
00445
case ID_IMEOPENCLOSE:
00446 {
00447
00448
BOOL fOpen =
fpImmGetOpenStatus(hIMC);
00449
00450
fpImmSetOpenStatus(hIMC, !fOpen);
00451 }
00452
break;
00453
00454
case ID_SOFTKBDOPENCLOSE:
00455 {
00456
DWORD fdwConversion;
00457
00458
if (
fpImmGetConversionStatus(hIMC, &fdwConversion,
NULL)) {
00459
00460
00461
00462
fpImmEnumInputContext(0,
SyncSoftKbdState,
00463 (fdwConversion & IME_CMODE_SOFTKBD) != IME_CMODE_SOFTKBD);
00464 }
00465 }
00466
break;
00467
00468
case ID_RECONVERTSTRING:
00469 {
00470
DWORD dwStrLen;
00471
DWORD cbLen;
00472
DWORD dwSize;
00473 LPRECONVERTSTRING lpRCS;
00474
00475
00476 dwStrLen = ped->
ichMaxSel - ped->
ichMinSel;
00477 cbLen = dwStrLen * ped->
cbChar;
00478 dwSize = cbLen +
sizeof(RECONVERTSTRING) + 8;
00479
00480 lpRCS = (LPRECONVERTSTRING)
UserLocalAlloc(0, dwSize);
00481
00482
if (lpRCS) {
00483 LPBYTE pText;
00484
00485 pText =
ECLock(ped);
00486
if (pText !=
NULL) {
00487 LPBYTE
lpDest;
00488
BOOL (WINAPI* fpSetCompositionStringAW)(HIMC,
DWORD, LPCVOID,
DWORD, LPCVOID,
DWORD);
00489
00490 lpRCS->dwSize = dwSize;
00491 lpRCS->dwVersion = 0;
00492
00493 lpRCS->dwStrLen =
00494 lpRCS->dwCompStrLen =
00495 lpRCS->dwTargetStrLen = dwStrLen;
00496
00497 lpRCS->dwStrOffset =
sizeof(RECONVERTSTRING);
00498 lpRCS->dwCompStrOffset =
00499 lpRCS->dwTargetStrOffset = 0;
00500
00501
lpDest = (LPBYTE)lpRCS +
sizeof(RECONVERTSTRING);
00502
00503 RtlCopyMemory(
lpDest, pText + ped->
ichMinSel * ped->
cbChar, cbLen);
00504
if (ped->
fAnsi) {
00505 LPBYTE psz = (LPBYTE)
lpDest;
00506 psz[cbLen] =
'\0';
00507 fpSetCompositionStringAW =
fpImmSetCompositionStringA;
00508 }
else {
00509 LPWSTR pwsz = (LPWSTR)
lpDest;
00510 pwsz[dwStrLen] =
L'\0';
00511 fpSetCompositionStringAW =
fpImmSetCompositionStringW;
00512 }
00513
00514
ECUnlock(ped);
00515
00516 UserAssert(fpSetCompositionStringAW !=
NULL);
00517
00518
ECInOutReconversionMode(ped,
TRUE);
00519
ECImmSetCompositionWindow(ped, 0, 0);
00520 fpSetCompositionStringAW(hIMC, SCS_SETRECONVERTSTRING, lpRCS, dwSize,
NULL, 0);
00521 }
00522
UserLocalFree(lpRCS);
00523 }
00524 }
00525
break;
00526
00527
default:
00528
00529 RIPMSG1(RIP_ERROR,
"ECDoIMEMenuCommand: unknown command id %d; should never reach here.", cmd);
00530
return FALSE;
00531 }
00532
00533 UserAssert(hIMC !=
NULL);
00534
fpImmReleaseContext(hwnd, hIMC);
00535
00536
return TRUE;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 void ECMenu(
00549 HWND hwnd,
00550
PED ped,
00551 LPPOINT pt)
00552 {
00553 HMENU hMenu;
00554
int cmd = 0;
00555
int x;
00556
int y;
00557
EditMenuItemState state = {
00558
FALSE,
00559
TRUE,
00560
TRUE,
00561
IS_IME_ENABLED() &&
fpImmIsIME(
THREAD_HKL()),
00562 };
00563
00564
00565
if (!ped->
fFocus)
00566
NtUserSetFocus(hwnd);
00567
00568
00569
if (!(hMenu = LoadMenu(
hmodUser, MAKEINTRESOURCE(
ID_EC_PROPERTY_MENU ))))
00570
return ;
00571
00572
00573
00574
if (ped->undoType ==
UNDO_NONE)
00575
EnableMenuItem(hMenu, WM_UNDO, MF_BYCOMMAND | MFS_GRAYED);
00576
00577
if (ped->
fReadOnly || ped->
charPasswordChar) {
00578
00579 state.
fDisableCut =
TRUE;
00580 }
else {
00581
00582
if (ped->
ichMinSel == ped->
ichMaxSel)
00583 state.
fDisableCut =
TRUE;
00584 }
00585
00586
00587
00588
00589
if (
NtUserIsClipboardFormatAvailable(CF_TEXT))
00590 state.
fDisablePaste =
FALSE;
00591
00592
if (state.
fDisableCut) {
00593
EnableMenuItem(hMenu, WM_CUT, MF_BYCOMMAND | MFS_GRAYED);
00594
EnableMenuItem(hMenu, WM_CLEAR, MF_BYCOMMAND | MFS_GRAYED);
00595 }
00596
00597
if (state.
fDisablePaste)
00598
EnableMenuItem(hMenu, WM_PASTE, MF_BYCOMMAND | MFS_GRAYED);
00599
00600
00601
if ((ped->
ichMinSel == ped->
ichMaxSel) || (ped->
charPasswordChar))
00602
EnableMenuItem(hMenu, WM_COPY, MF_BYCOMMAND | MFS_GRAYED);
00603
00604
00605
00606
if ((ped->
ichMinSel == 0) && (ped->
ichMaxSel == ped->
cch))
00607
EnableMenuItem(hMenu, EM_SETSEL, MF_BYCOMMAND | MFS_GRAYED);
00608
00609
if (ped->
pLpkEditCallout) {
00610 ped->
pLpkEditCallout->
EditSetMenu(ped, hMenu);
00611 }
else {
00612
NtUserDeleteMenu(hMenu,
ID_CNTX_DISPLAYCTRL, MF_BYCOMMAND);
00613
NtUserDeleteMenu(hMenu,
ID_CNTX_RTL, MF_BYCOMMAND);
00614
NtUserDeleteMenu(hMenu,
ID_CNTX_INSERTCTRL, MF_BYCOMMAND);
00615
00616
if (state.
fIME) {
00617
00618
00619 state.
fNeedSeparatorBeforeImeMenu =
FALSE;
00620 }
else {
00621
00622 HMENU hmenuSub =
GetSubMenu(hMenu, 0);
00623
int nItems =
GetMenuItemCount(hmenuSub) - 1;
00624
00625 UserAssert(nItems >= 0);
00626 UserAssert(
GetMenuState(hmenuSub, nItems, MF_BYPOSITION) & MF_SEPARATOR);
00627
00628 UserVerify(
NtUserDeleteMenu(hmenuSub, nItems, MF_BYPOSITION));
00629 }
00630 }
00631
00632
00633
if (state.
fIME) {
00634
ECSetIMEMenu(hMenu, hwnd, state);
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
if (pt->x == -1 && pt->y == -1) {
00655 RECT rc;
00656
00657
GetWindowRect(hwnd, &rc);
00658 x = rc.left + (rc.right - rc.left) / 2;
00659 y = rc.top + (rc.bottom - rc.top) / 2;
00660 }
else {
00661 x = pt->x;
00662 y = pt->y;
00663 }
00664
00665 cmd =
NtUserTrackPopupMenuEx(
GetSubMenu(hMenu, 0), TPM_NONOTIFY |
00666 TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
00667 x, y, hwnd,
NULL);
00668
00669
00670
NtUserDestroyMenu(hMenu);
00671
00672
if (cmd && (cmd != -1)) {
00673
if (ped->
pLpkEditCallout && cmd) {
00674 ped->
pLpkEditCallout->
EditProcessMenu(ped, cmd);
00675 }
00676
if (!state.
fIME || !
ECDoIMEMenuCommand(ped, cmd, hwnd)) {
00677
00678
SendMessage(hwnd, cmd, 0, (cmd == EM_SETSEL) ? 0xFFFFFFFF : 0
L );
00679 }
00680 }
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 void ECClearText(
PED ped) {
00693
if (!ped->
fReadOnly &&
00694 (ped->
ichMinSel < ped->
ichMaxSel)) {
00695
if (ped->
fSingle)
00696
SLEditWndProc(ped->
hwnd, ped, WM_CHAR, VK_BACK, 0
L );
00697
else
00698
MLEditWndProc(ped->
hwnd, ped, WM_CHAR, VK_BACK, 0
L );
00699 }
00700
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 void ECCutText(
PED ped) {
00713
00714
00715
if (!ped->
fReadOnly &&
00716 (ped->
ichMinSel < ped->
ichMaxSel) &&
00717
SendMessage(ped->
hwnd, WM_COPY, 0, 0
L)) {
00718
00719
00720
00721
ECClearText(ped);
00722 }
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 int ECGetModKeys(
int keyMods) {
00734
int scState;
00735
00736 scState = 0;
00737
00738
if (!keyMods) {
00739
if (
GetKeyState(VK_CONTROL) < 0)
00740 scState |=
CTRLDOWN;
00741
if (
GetKeyState(VK_SHIFT) < 0)
00742 scState |=
SHFTDOWN;
00743 }
else if (keyMods !=
NOMODIFY)
00744 scState = keyMods;
00745
00746
return scState;
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 UINT ECTabTheTextOut(
00771 HDC hdc,
00772
int xClipStPos,
00773
int xClipEndPos,
00774
int xStart,
00775
int y,
00776 LPSTR lpstring,
00777
int nCount,
00778 ICH ichString,
00779
PED ped,
00780
int iTabOrigin,
00781 BOOL fDraw,
00782 LPSTRIPINFO NegCInfoForStrip)
00783 {
00784
int nTabPositions;
00785 LPINT lpintTabStopPositions;
00786
00787
int cch;
00788
UINT textextent;
00789
int xEnd;
00790
int pixeltabstop = 0;
00791
int i;
00792
int cxCharWidth;
00793 RECT rc;
00794
BOOL fOpaque;
00795
BOOL fFirstPass =
TRUE;
00796
PINT charWidthBuff;
00797
00798
int iTabLength;
00799
int nConsecutiveTabs;
00800
int xStripStPos;
00801
int xStripEndPos;
00802
int xEndOfStrip;
00803
STRIPINFO RedrawStripInfo;
00804
STRIPINFO NegAInfo;
00805 LPSTR lpTab;
00806 LPWSTR lpwTab;
00807
UINT wNegCwidth, wNegAwidth;
00808
int xRightmostPoint = xClipStPos;
00809
int xTabStartPos;
00810
int iSavedBkMode = 0;
00811 WCHAR wchar;
00812 SIZE size;
00813 ABC abc ;
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
if (fDraw) {
00826
00827
00828 NegCInfoForStrip->nCount = 0;
00829 NegCInfoForStrip->XStartPos = xClipEndPos;
00830
00831
00832 RedrawStripInfo.
nCount = 0;
00833
00834 fOpaque = (GetBkMode(hdc) == OPAQUE) || (fDraw ==
ECT_SELECTED);
00835 }
00836
#if DBG
00837
else {
00838
00839
00840
00841
00842
if (nCount >
MAXLINELENGTH)
00843 RIPMSG0(RIP_WARNING,
"ECTabTheTextOut: nCount > MAXLINELENGTH");
00844 }
00845
#endif
00846
00847
00848 rc.left = xClipStPos;
00849 rc.right = xClipEndPos;
00850 rc.top = y;
00851 rc.bottom = y + ped->
lineHeight;
00852
00853
00854
if (!lpstring || !nCount) {
00855
if (fDraw)
00856 ExtTextOutW(hdc, xClipStPos, y,
00857 (fOpaque ? ETO_OPAQUE | ETO_CLIPPED : ETO_CLIPPED),
00858 &rc,
L"", 0, 0
L);
00859
return(0
L);
00860 }
00861
00862
00863
00864
00865 xEnd = xStart;
00866
00867 cxCharWidth = ped->
aveCharWidth;
00868
00869 nTabPositions = (ped->
pTabStops ? *(ped->
pTabStops) : 0);
00870
if (ped->
pTabStops) {
00871 lpintTabStopPositions = (LPINT)(ped->
pTabStops+1);
00872
if (nTabPositions == 1) {
00873 pixeltabstop = lpintTabStopPositions[0];
00874
if (!pixeltabstop)
00875 pixeltabstop = 1;
00876 }
00877 }
else {
00878 lpintTabStopPositions =
NULL;
00879 pixeltabstop = 8*cxCharWidth;
00880 }
00881
00882
00883
00884
00885
00886 RedrawStrip:
00887
while (nCount) {
00888 wNegCwidth = ped->
wMaxNegC;
00889
00890
00891
00892
00893
00894
00895
if (ped->
charWidthBuffer) {
00896 textextent = 0;
00897 cch = nCount;
00898
00899
if (ped->
fTrueType) {
00900
00901
UINT iRightmostPoint = 0;
00902
UINT wCharIndex;
00903 PABC pABCwidthBuff;
00904
00905 pABCwidthBuff = (PABC) ped->
charWidthBuffer;
00906
00907
if ( ped->
fAnsi ) {
00908
for (i = 0; i < nCount; i++) {
00909
00910
if (lpstring[i] == VK_TAB) {
00911 cch = i;
00912
break;
00913 }
00914
00915 wCharIndex = (
UINT)(((
unsigned char *)lpstring)[i]);
00916
if (wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH) {
00917 textextent += (
UINT)(pABCwidthBuff[wCharIndex].abcA +
00918 pABCwidthBuff[wCharIndex].abcB);
00919 }
else {
00920 GetCharABCWidthsA(hdc, wCharIndex, wCharIndex, &abc);
00921 textextent += abc.abcA + abc.abcB ;
00922 }
00923
00924
if (textextent > iRightmostPoint)
00925 iRightmostPoint = textextent;
00926
00927
if (wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH) {
00928 textextent += pABCwidthBuff[wCharIndex].abcC;
00929 }
else {
00930 textextent += abc.abcC;
00931 }
00932
00933
if (textextent > iRightmostPoint)
00934 iRightmostPoint = textextent;
00935 }
00936
00937 }
else {
00938
for (i = 0; i < nCount; i++) {
00939 WCHAR UNALIGNED * lpwstring = (WCHAR UNALIGNED *)lpstring;
00940
00941
if (lpwstring[i] == VK_TAB) {
00942 cch = i;
00943
break;
00944 }
00945
00946 wCharIndex = lpwstring[i] ;
00947
if ( wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH )
00948 textextent += pABCwidthBuff[wCharIndex].abcA +
00949 pABCwidthBuff[wCharIndex].abcB;
00950
else {
00951 GetCharABCWidthsW(hdc, wCharIndex, wCharIndex, &abc) ;
00952 textextent += abc.abcA + abc.abcB ;
00953 }
00954
00955
00956
00957
00958
00959
if (textextent > iRightmostPoint)
00960 iRightmostPoint = textextent;
00961
00962
if ( wCharIndex <
CHAR_WIDTH_BUFFER_LENGTH )
00963 textextent += pABCwidthBuff[wCharIndex].abcC;
00964
else
00965 textextent += abc.abcC ;
00966
00967
if (textextent > iRightmostPoint)
00968 iRightmostPoint = textextent;
00969 }
00970 }
00971
00972 wNegCwidth = (
int)(iRightmostPoint - textextent);
00973 }
else {
00974
00975
00976
00977 charWidthBuff = ped->
charWidthBuffer;
00978
00979
if ( ped->
fAnsi ) {
00980
00981
for (i = 0; i < nCount; i++) {
00982
if (lpstring[i] == VK_TAB) {
00983 cch = i;
00984
break;
00985 }
00986
00987
00988
00989
00990
if (ped->
fDBCS && (i+1 < nCount)
00991 &&
ECIsDBCSLeadByte(ped,lpstring[i])) {
00992 GetTextExtentPointA(hdc, &lpstring[i], 2, &size);
00993 textextent += size.cx;
00994 i++;
00995 }
else if ((UCHAR)lpstring[i] >=
CHAR_WIDTH_BUFFER_LENGTH) {
00996
00997
00998 GetTextExtentPointA(hdc, &lpstring[i], 1, &size);
00999 textextent += size.cx;
01000 }
else {
01001 textextent += (
UINT)(charWidthBuff[(
UINT)(((
unsigned char *)lpstring)[i])]);
01002 }
01003 }
01004 }
else {
01005 LPWSTR lpwstring = (LPWSTR) lpstring ;
01006
INT cchUStart;
01007
01008
for (i = 0; i < nCount; i++) {
01009
if (lpwstring[i] == VK_TAB) {
01010 cch = i;
01011
break;
01012 }
01013
01014 wchar = lpwstring[i];
01015
if (wchar >=
CHAR_WIDTH_BUFFER_LENGTH) {
01016
01017
01018
01019
01020
01021
01022
01023 cchUStart = i;
01024
while (wchar >=
CHAR_WIDTH_BUFFER_LENGTH &&
01025 wchar != VK_TAB && i < nCount) {
01026 wchar = lpwstring[++i];
01027 }
01028
01029 GetTextExtentPointW(hdc, (LPWSTR)lpwstring + cchUStart,
01030 i-cchUStart, &size);
01031 textextent += size.cx;
01032
01033
01034
if (wchar == VK_TAB || i >= nCount) {
01035 cch = i;
01036
break;
01037 }
01038
01039
01040
01041 }
01042
01043
01044
01045 textextent += ped->
charWidthBuffer[wchar];
01046 }
01047 }
01048 }
01049
01050 nCount -= cch;
01051 }
else {
01052
01053
01054
01055
01056
if ( ped->
fAnsi ) {
01057 cch = (
int)
ECFindTabA(lpstring, nCount);
01058 GetTextExtentPointA(hdc, lpstring, cch, &size) ;
01059 }
else {
01060 cch = (
int)
ECFindTabW((LPWSTR) lpstring, nCount);
01061 GetTextExtentPointW(hdc, (LPWSTR)lpstring, cch, &size);
01062 }
01063 nCount -= cch;
01064
01065
01066
01067 textextent = (size.cx - ped->
charOverhang);
01068 }
01069
01070
01071
01072
01073
01074 xStripStPos = xEnd;
01075 xEnd += (
int)textextent;
01076 xStripEndPos = xEnd;
01077
01078
01079
if (fFirstPass && fDraw) {
01080 xRightmostPoint =
max(xStripEndPos + (
int)wNegCwidth, xRightmostPoint);
01081
01082
01083
if (xRightmostPoint > xClipEndPos) {
01084
if (!NegCInfoForStrip->nCount) {
01085 NegCInfoForStrip->lpString = lpstring;
01086 NegCInfoForStrip->ichString = ichString;
01087 NegCInfoForStrip->nCount = nCount+cch;
01088 NegCInfoForStrip->XStartPos = xStripStPos;
01089 }
01090 }
01091 }
01092
01093
if ( ped->
fAnsi )
01094 lpTab = lpstring + cch;
01095
else
01096 lpwTab = ((LPWSTR)lpstring) + cch ;
01097
01098
01099
01100 nConsecutiveTabs = 0;
01101
while (nCount &&
01102 (ped->
fAnsi ? (*lpTab == VK_TAB) : (*lpwTab == VK_TAB))) {
01103
01104 xTabStartPos = xEnd;
01105
if (pixeltabstop)
01106 xEnd = (((xEnd-iTabOrigin)/pixeltabstop)*pixeltabstop) +
01107 pixeltabstop + iTabOrigin;
01108
else {
01109
for (i = 0; i < nTabPositions; i++) {
01110
if (xEnd < (lpintTabStopPositions[i] + iTabOrigin)) {
01111 xEnd = (lpintTabStopPositions[i] + iTabOrigin);
01112
break;
01113 }
01114 }
01115
01116
01117
01118
if (i == nTabPositions) {
01119 pixeltabstop = 8*cxCharWidth;
01120 xEnd = ((xEnd - iTabOrigin)/pixeltabstop)*pixeltabstop +
01121 pixeltabstop + iTabOrigin;
01122 }
01123 }
01124
01125
if (fFirstPass && fDraw) {
01126 xRightmostPoint =
max(xEnd, xRightmostPoint);
01127
01128
01129
if (xRightmostPoint > xClipEndPos) {
01130
if (!NegCInfoForStrip->nCount) {
01131 NegCInfoForStrip->ichString = ichString + cch + nConsecutiveTabs;
01132 NegCInfoForStrip->nCount = nCount;
01133 NegCInfoForStrip->lpString = (ped->
fAnsi ?
01134 lpTab : (LPSTR) lpwTab);
01135 NegCInfoForStrip->XStartPos = xTabStartPos;
01136 }
01137 }
01138 }
01139
01140 nConsecutiveTabs++;
01141 nCount--;
01142 ped->
fAnsi ? lpTab++ : (LPSTR) (lpwTab++) ;
01143 }
01144
01145
if (fDraw) {
01146
if (fFirstPass) {
01147
01148
if (!nCount)
01149 rc.right = xEnd;
01150
else {
01151
01152 iTabLength = xEnd - xStripEndPos;
01153
01154
01155
01156
if ((wNegCwidth + (wNegAwidth = ped->
wMaxNegA)) > (
UINT)iTabLength) {
01157
01158
01159 wNegAwidth =
GetActualNegA(
01160 hdc,
01161 ped,
01162 xEnd,
01163 lpstring + (cch + nConsecutiveTabs)*ped->
cbChar,
01164 ichString + cch + nConsecutiveTabs,
01165 nCount,
01166 &NegAInfo);
01167 }
01168
01169
01170
if ((wNegCwidth + wNegAwidth) <= (
UINT)iTabLength) {
01171
01172 rc.right = xEnd - wNegAwidth;
01173 }
else {
01174
01175 rc.right = xEnd;
01176
01177
01178
if (wNegCwidth > (
UINT)iTabLength) {
01179
01180
if (RedrawStripInfo.
nCount) {
01181
01182
01183 RedrawStripInfo.
nCount = (ichString -
01184 RedrawStripInfo.
ichString) + cch;
01185 }
else {
01186 RedrawStripInfo.
nCount = cch;
01187 RedrawStripInfo.
lpString = lpstring;
01188 RedrawStripInfo.
ichString = ichString;
01189 RedrawStripInfo.
XStartPos = xStripStPos;
01190 }
01191 }
01192
01193
if (wNegAwidth) {
01194
01195
if (RedrawStripInfo.
nCount) {
01196
01197
01198 RedrawStripInfo.
nCount = (NegAInfo.
ichString - RedrawStripInfo.
ichString) +
01199 NegAInfo.
nCount;
01200 }
else
01201 RedrawStripInfo = NegAInfo;
01202 }
01203 }
01204 }
01205 }
01206
01207
if (rc.left < xClipEndPos) {
01208
if (fFirstPass) {
01209
01210
if ((!nCount) && (xClipEndPos ==
MAXCLIPENDPOS))
01211 rc.right =
max(rc.right, xClipEndPos);
01212
else
01213 rc.right =
min(rc.right, xClipEndPos);
01214 }
01215
01216
01217
if (rc.left < rc.right)
01218
if ( ped->
fAnsi )
01219 ExtTextOutA(hdc,
01220 xStripStPos,
01221 y,
01222 (fFirstPass && fOpaque ? (ETO_OPAQUE | ETO_CLIPPED) : ETO_CLIPPED),
01223 (LPRECT)&rc, lpstring, cch, 0
L);
01224
else
01225 ExtTextOutW(hdc,
01226 xStripStPos,
01227 y,
01228 (fFirstPass && fOpaque ? (ETO_OPAQUE | ETO_CLIPPED) : ETO_CLIPPED),
01229 (LPRECT)&rc, (LPWSTR)lpstring, cch, 0
L);
01230
01231 }
01232
01233
if (fFirstPass)
01234 rc.left =
max(rc.right, xClipStPos);
01235 ichString += (cch+nConsecutiveTabs);
01236 }
01237
01238
01239 lpstring += (cch + nConsecutiveTabs) * ped->
cbChar;
01240 }
01241
01242 xEndOfStrip = xEnd;
01243
01244
01245
if (fFirstPass && fDraw && RedrawStripInfo.
nCount) {
01246 iSavedBkMode = SetBkMode(hdc, TRANSPARENT);
01247 fFirstPass =
FALSE;
01248
01249 nCount = RedrawStripInfo.
nCount;
01250 rc.left = xClipStPos;
01251 rc.right = xClipEndPos;
01252 lpstring = RedrawStripInfo.
lpString;
01253 ichString = RedrawStripInfo.
ichString;
01254 xEnd = RedrawStripInfo.
XStartPos;
01255
goto RedrawStrip;
01256 }
01257
01258
if (iSavedBkMode)
01259 SetBkMode(hdc, iSavedBkMode);
01260
01261
return((
UINT)(xEndOfStrip - xStart));
01262 }
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281 ICH ECCchInWidth(
01282
PED ped,
01283 HDC hdc,
01284 LPSTR lpText,
01285 ICH cch,
01286
int width,
01287 BOOL fForward)
01288 {
01289
int stringExtent;
01290
int cchhigh;
01291
int cchnew = 0;
01292
int cchlow = 0;
01293 SIZE size;
01294 LPSTR lpStart;
01295
01296
if ((width <= 0) || !cch)
01297
return (0);
01298
01299
01300
01301
01302
01303
01304
01305
01306
if (ped->
fNonPropFont && ped->
fSingle && !ped->
fDBCS) {
01307
return (
ECAdjustIch( ped, lpText,
umin(width/ped->
aveCharWidth,(
int)cch)));
01308 }
01309
01310
01311
01312
01313
if (ped->
charPasswordChar) {
01314
return (
umin(width / ped->
cPasswordCharWidth, (
int)cch));
01315 }
01316
01317
01318
01319
01320 cch =
umin(
MAXLINELENGTH, cch);
01321
01322 cchhigh = cch + 1;
01323
while (cchlow < cchhigh - 1) {
01324 cchnew =
umax((cchhigh - cchlow) / 2, 1) + cchlow;
01325
01326 lpStart = lpText;
01327
01328
01329
01330
01331
01332
01333
if (!fForward)
01334 lpStart += (cch - cchnew)*ped->
cbChar;
01335
01336
if (ped->
fSingle) {
01337
if (ped->
fAnsi)
01338 GetTextExtentPointA(hdc, (LPSTR)lpStart, cchnew, &size);
01339
else
01340 GetTextExtentPointW(hdc, (LPWSTR)lpStart, cchnew, &size);
01341 stringExtent = size.cx;
01342 }
else {
01343 stringExtent =
ECTabTheTextOut(hdc, 0, 0, 0, 0,
01344 lpStart,
01345 cchnew, 0,
01346 ped, 0,
ECT_CALC,
NULL );
01347 }
01348
01349
if (stringExtent > width) {
01350 cchhigh = cchnew;
01351 }
else {
01352 cchlow = cchnew;
01353 }
01354 }
01355
01356
01357
01358 cchlow =
ECAdjustIch( ped, lpText, cchlow );
01359
return (cchlow);
01360 }
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371 ICH ECFindTabA(
01372 LPSTR lpstr,
01373 ICH cch)
01374 {
01375 LPSTR copylpstr = lpstr;
01376
01377
if (!cch)
01378
return 0;
01379
01380
while (*lpstr != VK_TAB) {
01381 lpstr++;
01382
if (--cch == 0)
01383
break;
01384 }
01385
return ((
ICH)(lpstr - copylpstr));
01386 }
01387
01388 ICH ECFindTabW(
01389 LPWSTR lpstr,
01390 ICH cch)
01391 {
01392 LPWSTR copylpstr = lpstr;
01393
01394
if (!cch)
01395
return 0;
01396
01397
while (*lpstr != VK_TAB) {
01398 lpstr++;
01399
if (--cch == 0)
01400
break;
01401 }
01402
return ((
ICH)(lpstr - copylpstr));
01403 }
01404
01405
01406
01407
01408
01409
01410
01411
01412 HBRUSH
ECGetBrush(
PED ped, HDC hdc)
01413 {
01414 HBRUSH hbr;
01415
BOOL f40Compat;
01416
01417 f40Compat = (
GETAPPVER() >=
VER40);
01418
01419
01420
if ((ped->
fReadOnly || ped->
fDisabled) && f40Compat) {
01421 hbr =
ECGetControlBrush(ped, hdc, WM_CTLCOLORSTATIC);
01422 }
else
01423 hbr =
ECGetControlBrush(ped, hdc, WM_CTLCOLOREDIT);
01424
01425
if (ped->
fDisabled && (ped->
fSingle || f40Compat)) {
01426
DWORD rgb;
01427
01428
01429 rgb =
GetSysColor(COLOR_GRAYTEXT);
01430
if (rgb != GetBkColor(hdc))
01431 SetTextColor(hdc, rgb);
01432 }
01433
return(hbr);
01434 }
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446 void NextWordCallBack(
01447
PED ped,
01448 ICH ichStart,
01449 BOOL fLeft,
01450 ICH *pichMin,
01451 ICH *pichMax )
01452 {
01453
ICH ichMinSel;
01454
ICH ichMaxSel;
01455 LPSTR pText;
01456
01457 pText =
ECLock(ped);
01458
01459
if (fLeft || (!(
BOOL)
CALLWORDBREAKPROC(ped->
lpfnNextWord, (LPSTR)pText,
01460 ichStart, ped->
cch, WB_ISDELIMITER) &&
01461 (ped->
fAnsi ? (*(pText + ichStart) != VK_RETURN) : (*((LPWSTR)pText + ichStart) != VK_RETURN))
01462 ))
01463 ichMinSel =
CALLWORDBREAKPROC(*ped->
lpfnNextWord, (LPSTR)pText, ichStart, ped->
cch, WB_LEFT);
01464
else
01465 ichMinSel =
CALLWORDBREAKPROC(*ped->
lpfnNextWord, (LPSTR)pText, ichStart, ped->
cch, WB_RIGHT);
01466
01467 ichMaxSel =
min(ichMinSel + 1, ped->
cch);
01468
01469
if (ped->
fAnsi) {
01470
if (*(pText + ichMinSel) == VK_RETURN) {
01471
if (ichMinSel > 0 && *(pText + ichMinSel - 1) == VK_RETURN) {
01472
01473
01474
01475
01476 ichMinSel--;
01477 }
else if (*(pText+ichMinSel + 1) == VK_RETURN) {
01478
01479
01480
01481
01482 ichMaxSel++;
01483 }
01484 }
01485 }
else {
01486
if (*((LPWSTR)pText + ichMinSel) == VK_RETURN) {
01487
if (ichMinSel > 0 && *((LPWSTR)pText + ichMinSel - 1) == VK_RETURN) {
01488
01489
01490
01491
01492 ichMinSel--;
01493 }
else if (*((LPWSTR)pText+ichMinSel + 1) == VK_RETURN) {
01494
01495
01496
01497
01498 ichMaxSel++;
01499 }
01500 }
01501 }
01502 ichMaxSel =
CALLWORDBREAKPROC(ped->
lpfnNextWord, (LPSTR)pText, ichMaxSel, ped->
cch, WB_RIGHT);
01503
ECUnlock(ped);
01504
01505
if (pichMin) *pichMin = ichMinSel;
01506
if (pichMax) *pichMax = ichMaxSel;
01507 }
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518 void NextWordLpkCallBack(
01519
PED ped,
01520 ICH ichStart,
01521 BOOL fLeft,
01522 ICH *pichMin,
01523 ICH *pichMax)
01524 {
01525 PSTR pText =
ECLock(ped);
01526 HDC hdc =
ECGetEditDC(ped,
TRUE);
01527
01528 ped->
pLpkEditCallout->
EditNextWord(ped, hdc, pText, ichStart, fLeft, pichMin, pichMax);
01529
01530
ECReleaseEditDC(ped, hdc,
TRUE);
01531
ECUnlock(ped);
01532 }
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552 void ECWord(
01553
PED ped,
01554 ICH ichStart,
01555 BOOL fLeft,
01556 ICH *pichMin,
01557 ICH *pichMax )
01558 {
01559
BOOL charLocated =
FALSE;
01560
BOOL spaceLocated =
FALSE;
01561
01562
if ((!ichStart && fLeft) || (ichStart == ped->
cch && !fLeft)) {
01563
01564
01565
01566
01567
01568
if (pichMin) *pichMin=0;
01569
if (pichMax) *pichMax=0;
01570
return;
01571 }
01572
01573
01574
01575
01576
if (ped->
charPasswordChar) {
01577
if (pichMin) *pichMin=0;
01578
if (pichMax) *pichMax=ped->
cch;
01579
return;
01580 }
01581
01582
if (ped->
fAnsi) {
01583 PSTR pText;
01584 PSTR pWordMinSel;
01585 PSTR pWordMaxSel;
01586 PSTR pPrevChar;
01587
01588 UserAssert(ped->
cbChar ==
sizeof(
CHAR));
01589
01590
if (ped->
lpfnNextWord) {
01591
NextWordCallBack(ped, ichStart, fLeft, pichMin, pichMax);
01592
return;
01593 }
01594
01595
if (ped->
pLpkEditCallout) {
01596
NextWordLpkCallBack(ped, ichStart, fLeft, pichMin, pichMax);
01597
return;
01598 }
01599
01600 pText =
ECLock(ped);
01601 pWordMinSel = pWordMaxSel = pText + ichStart;
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
if (fLeft || !
ISDELIMETERA(*pWordMinSel) && *pWordMinSel != 0x0D) {
01622
01623
01624
01625
01626
01627
01628
01629
01630
while (pWordMinSel > pText && ((!
ISDELIMETERA(*(pWordMinSel - 1)) &&
01631 *(pWordMinSel - 1) != 0x0A) || !charLocated)) {
01632
01633
01634
01635
01636 pPrevChar =
ECAnsiPrev( ped, pText, pWordMinSel );
01637
01638
01639
01640
01641
01642
01643
01644
if ( !fLeft && (
ISDELIMETERA( *pPrevChar ) ||
01645 *pPrevChar == 0x0A ||
01646
ECIsDBCSLeadByte(ped, *pWordMinSel) ||
01647 pWordMinSel - pPrevChar == 2 ) ) {
01648
01649
01650
01651
01652
01653
break;
01654 }
01655
01656
if ( pWordMinSel - pPrevChar == 2 ) {
01657
01658
01659
01660
01661
01662
01663
01664
if ( ! charLocated ) {
01665 pWordMinSel = pPrevChar;
01666 }
01667
break;
01668 }
01669 pWordMinSel = pPrevChar;
01670
01671
if (!
ISDELIMETERA(*pWordMinSel) && *pWordMinSel != 0x0A) {
01672
01673
01674
01675
01676
01677 charLocated =
TRUE;
01678
01679
01680
01681
01682
if (*pWordMinSel == 0x0D)
01683
break;
01684 }
01685 }
01686 }
else {
01687
while ((
ISDELIMETERA(*pWordMinSel) || *pWordMinSel == 0x0A) && pWordMinSel < pText + ped->
cch)
01688 pWordMinSel++;
01689 }
01690
01691
01692
01693
01694 pWordMaxSel =
ECAnsiNext(ped, pWordMinSel);
01695 pWordMaxSel =
min(pWordMaxSel, pText + ped->
cch);
01696
01697
01698
01699
01700
01701
01702
01703
if ( ( pWordMaxSel - pWordMinSel == 2 ) && !
ISDELIMETERA(*pWordMaxSel) )
01704
goto FastReturnA;
01705
if (*pWordMinSel == 0x0D) {
01706
if (pWordMinSel > pText && *(pWordMinSel - 1) == 0x0D)
01707
01708 pWordMinSel--;
01709
else if (*(pWordMinSel + 1) == 0x0D)
01710
01711 pWordMaxSel++;
01712 }
01713
01714
01715
01716
01717
01718
01719
if (
ISDELIMETERA(*pWordMaxSel))
01720 spaceLocated =
TRUE;
01721
01722
01723
01724
01725
01726
01727
01728
while ((pWordMaxSel < pText + ped->
cch) && (!spaceLocated || (
ISDELIMETERA(*pWordMaxSel)))) {
01729
if (*pWordMaxSel == 0x0D)
01730
break;
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
if (
ECIsDBCSLeadByte( ped, *pWordMaxSel))
01741
break;
01742
01743 pWordMaxSel++;
01744
01745
if (
ISDELIMETERA(*pWordMaxSel))
01746 spaceLocated =
TRUE;
01747
01748
if (*(pWordMaxSel - 1) == 0x0A)
01749
break;
01750 }
01751
01752
01753
01754
01755 FastReturnA:
01756
ECUnlock(ped);
01757
01758
if (pichMin) *pichMin = (
ICH)(pWordMinSel - pText);
01759
if (pichMax) *pichMax = (
ICH)(pWordMaxSel - pText);
01760
return;
01761
01762 }
else {
01763 LPWSTR pwText;
01764 LPWSTR pwWordMinSel;
01765 LPWSTR pwWordMaxSel;
01766
BOOL charLocated =
FALSE;
01767
BOOL spaceLocated =
FALSE;
01768 PWSTR pwPrevChar;
01769
01770 UserAssert(ped->
cbChar ==
sizeof(WCHAR));
01771
01772
if (ped->
lpfnNextWord) {
01773
NextWordCallBack(ped, ichStart, fLeft, pichMin, pichMax);
01774
return;
01775 }
01776
01777
if (ped->
pLpkEditCallout) {
01778
NextWordLpkCallBack(ped, ichStart, fLeft, pichMin, pichMax);
01779
return;
01780 }
01781
01782 pwText = (LPWSTR)
ECLock(ped);
01783 pwWordMinSel = pwWordMaxSel = pwText + ichStart;
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
if (fLeft || (!
ISDELIMETERW(*pwWordMinSel) && *pwWordMinSel != 0x0D))
01805
01806
01807
01808
01809
01810 {
01811
while (pwWordMinSel > pwText && ((!
ISDELIMETERW(*(pwWordMinSel - 1)) && *(pwWordMinSel - 1) != 0x0A) || !charLocated)) {
01812
01813
01814
01815 pwPrevChar = pwWordMinSel - 1;
01816
01817
01818
01819
01820
01821
01822
01823
if (!fLeft && (
ISDELIMETERW( *pwPrevChar) ||
01824 *pwPrevChar == 0x0A ||
01825
UserIsFullWidth(CP_ACP,*pwWordMinSel) ||
01826
UserIsFullWidth(CP_ACP,*pwPrevChar))) {
01827
01828
01829
01830
01831
01832
break;
01833 }
01834
01835
if (
UserIsFullWidth(CP_ACP,*pwPrevChar)) {
01836
01837
01838
01839
01840
01841
01842
01843
01844
if ( ! charLocated ) {
01845 pwWordMinSel = pwPrevChar;
01846 }
01847
break;
01848 }
01849 pwWordMinSel = pwPrevChar;
01850
01851
if (!
ISDELIMETERW(*pwWordMinSel) && *pwWordMinSel != 0x0A)
01852
01853
01854
01855 {
01856 charLocated =
TRUE;
01857
01858
01859
01860
01861
if (*pwWordMinSel == 0x0D)
01862
break;
01863 }
01864 }
01865 }
else {
01866
01867
01868
01869
01870
01871
while ((
ISDELIMETERW(*pwWordMinSel) || *pwWordMinSel == 0x0A) && pwWordMinSel < pwText + ped->
cch)
01872 pwWordMinSel++;
01873 }
01874
01875 pwWordMaxSel =
min((pwWordMinSel + 1), (pwText + ped->
cch));
01876
01877
01878
01879
01880
01881
01882
01883
if (
UserIsFullWidth(CP_ACP,*pwWordMinSel) && !
ISDELIMETERW(*pwWordMaxSel))
01884
goto FastReturnW;
01885
if (*pwWordMinSel == 0x0D) {
01886
if (pwWordMinSel > pwText && *(pwWordMinSel - 1) == 0x0D)
01887
01888 pwWordMinSel--;
01889
else if (*(pwWordMinSel + 1) == 0x0D)
01890
01891 pwWordMaxSel++;
01892 }
01893
01894
01895
01896
01897
01898
01899
if (
ISDELIMETERW(*pwWordMaxSel))
01900 spaceLocated =
TRUE;
01901
01902
01903
01904
01905
01906
01907
01908
while ((pwWordMaxSel < pwText + ped->
cch) && (!spaceLocated || (
ISDELIMETERW(*pwWordMaxSel)))) {
01909
if (*pwWordMaxSel == 0x0D)
01910
break;
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
if (
UserIsFullWidth(CP_ACP,*pwWordMaxSel))
01922
break;
01923
01924 pwWordMaxSel++;
01925
01926
if (
ISDELIMETERW(*pwWordMaxSel))
01927 spaceLocated =
TRUE;
01928
01929
01930
if (*(pwWordMaxSel - 1) == 0x0A)
01931
break;
01932 }
01933
01934
01935
01936
01937 FastReturnW:
01938
ECUnlock(ped);
01939
01940
if (pichMin) *pichMin = (
ICH)(pwWordMinSel - pwText);
01941
if (pichMax) *pichMax = (
ICH)(pwWordMaxSel - pwText);
01942
return;
01943 }
01944 }
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955 void ECSaveUndo(
PUNDO pundoFrom,
PUNDO pundoTo, BOOL fClear)
01956 {
01957
01958
01959
01960 RtlCopyMemory(pundoTo, pundoFrom,
sizeof(
UNDO));
01961
01962
01963
01964
01965
if (fClear)
01966 RtlZeroMemory(pundoFrom,
sizeof(
UNDO) );
01967 }
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977 void ECEmptyUndo(
01978
PUNDO pundo )
01979 {
01980
if (pundo->
hDeletedText)
01981
UserGlobalFree(pundo->
hDeletedText);
01982
01983 RtlZeroMemory(pundo,
sizeof(
UNDO) );
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996 void ECMergeUndoInsertInfo(
PUNDO pundo, ICH ichInsert, ICH cchInsert) \
01997 {
01998
01999
02000
02001
if (pundo->undoType ==
UNDO_NONE) {
02002 pundo->undoType =
UNDO_INSERT;
02003 pundo->ichInsStart = ichInsert;
02004 pundo->ichInsEnd = ichInsert+cchInsert;
02005 }
else if (pundo->undoType &
UNDO_INSERT) {
02006
02007
02008
02009
02010
if (pundo->ichInsEnd == ichInsert)
02011 pundo->ichInsEnd += cchInsert;
02012
else {
02013
02014 UNDOINSERT:
02015
02016
02017
02018
02019
02020
if ((pundo->undoType &
UNDO_DELETE) && (pundo->ichDeleted != ichInsert)) {
02021
02022
02023
02024
02025
if (pundo->hDeletedText)
02026
UserGlobalFree(pundo->hDeletedText);
02027
02028 pundo->hDeletedText =
NULL;
02029 pundo->ichDeleted = 0xFFFFFFFF;
02030 pundo->undoType &= ~
UNDO_DELETE;
02031 }
02032
02033
02034
02035
02036 pundo->ichInsStart = ichInsert;
02037 pundo->ichInsEnd = ichInsert + cchInsert;
02038 pundo->undoType |=
UNDO_INSERT;
02039 }
02040 }
else if (pundo->undoType ==
UNDO_DELETE) {
02041
02042
goto UNDOINSERT;
02043 }
02044 }
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059 BOOL ECInsertText(
02060
PED ped,
02061 LPSTR lpText,
02062 ICH* pcchInsert)
02063 {
02064 PSTR pedText;
02065 PSTR pTextBuff;
02066 LONG style;
02067 HANDLE hTextCopy;
02068
DWORD allocamt;
02069
02070
02071
02072
02073
02074 *pcchInsert =
ECAdjustIch(ped, lpText, *pcchInsert);
02075
02076
if (!*pcchInsert)
02077
return TRUE;
02078
02079
02080
02081
02082
if (*pcchInsert >= (ped->
cchAlloc - ped->
cch)) {
02083
02084
02085
02086
02087
02088 allocamt = (ped->
cch + *pcchInsert) * ped->
cbChar;
02089 allocamt +=
CCHALLOCEXTRA;
02090
02091
02092 hTextCopy =
LOCALREALLOC(ped->
hText, allocamt,
LHND, ped->
hInstance, &lpText);
02093
if (hTextCopy) {
02094 ped->
hText = hTextCopy;
02095 }
else {
02096
return FALSE;
02097 }
02098
02099
02100
02101
02102
02103 ped->
cchAlloc =
LOCALSIZE(ped->
hText, ped->
hInstance) / ped->
cbChar;
02104 }
02105
02106
02107
02108
02109
02110 pedText =
ECLock(ped);
02111
02112
if (ped->
pLpkEditCallout) {
02113 HDC hdc;
02114
INT iResult;
02115
02116 hdc =
ECGetEditDC (ped,
TRUE);
02117 iResult = ped->
pLpkEditCallout->
EditVerifyText (ped, hdc, pedText, ped->
ichCaret, lpText, *pcchInsert);
02118
ECReleaseEditDC (ped, hdc,
TRUE);
02119
02120
if (iResult == 0) {
02121
ECUnlock (ped);
02122
return TRUE;
02123 }
02124 }
02125
02126
02127
02128
02129 pTextBuff = pedText + ped->
ichCaret * ped->
cbChar;
02130
02131
if (ped->
ichCaret != ped->
cch) {
02132
02133
02134
02135
02136
02137 memmove(pTextBuff + *pcchInsert * ped->
cbChar, pTextBuff, (ped->
cch-ped->
ichCaret) * ped->
cbChar);
02138 }
02139
02140
02141
02142
02143
02144
02145 memmove(pTextBuff, lpText, *pcchInsert * ped->
cbChar);
02146 ped->
cch += *pcchInsert;
02147
02148
02149
02150
02151 style = ped->
pwnd->style;
02152
02153
02154
02155
02156
if (style & ES_LOWERCASE) {
02157
if (ped->
fAnsi)
02158
CharLowerBuffA((LPSTR)pTextBuff, *pcchInsert);
02159
else
02160
CharLowerBuffW((LPWSTR)pTextBuff, *pcchInsert);
02161 }
else {
02162
if (style & ES_UPPERCASE) {
02163
if (ped->
fAnsi) {
02164
CharUpperBuffA(pTextBuff, *pcchInsert);
02165 }
else {
02166
CharUpperBuffW((LPWSTR)pTextBuff, *pcchInsert);
02167 }
02168 }
02169 }
02170
02171
02172
02173
02174
if ((style & ES_OEMCONVERT) &&
02175
02176
02177
02178 (!
IS_DBCS_ENABLED() ||
GETAPPVER() >=
VER50 || GetOEMCP() != GetACP())) {
02179
02180
ICH i;
02181
02182
if (ped->
fAnsi) {
02183
for (i = 0; i < *pcchInsert; i++) {
02184
02185
02186
02187
02188
02189
02190
if (
IS_DBCS_ENABLED() &&
ECIsDBCSLeadByte(ped, *(lpText+i))) {
02191 i++;
02192
continue;
02193 }
02194
02195
02196
02197
02198
02199
02200
02201
if (ped->
charSet != GREEK_CHARSET &&
IsCharLowerA(*(pTextBuff + i))) {
02202
CharUpperBuffA(pTextBuff + i, 1);
02203
CharToOemBuffA(pTextBuff + i, pTextBuff + i, 1);
02204
OemToCharBuffA(pTextBuff + i, pTextBuff + i, 1);
02205
CharLowerBuffA(pTextBuff + i, 1);
02206 }
else {
02207
CharToOemBuffA(pTextBuff + i, pTextBuff + i, 1);
02208
OemToCharBuffA(pTextBuff + i, pTextBuff + i, 1);
02209 }
02210 }
02211 }
else {
02212
02213
02214
02215 UCHAR ch[4];
02216 LPWSTR lpTextW = (LPWSTR)pTextBuff;
02217
02218
for (i = 0; i < *pcchInsert; i++) {
02219
if (*(lpTextW + i) ==
UNICODE_CARRIAGERETURN ||
02220 *(lpTextW + i) ==
UNICODE_LINEFEED ||
02221 *(lpTextW + i) ==
UNICODE_TAB) {
02222
continue;
02223 }
02224
02225
02226
02227
02228
02229
02230
if (ped->
charSet != GREEK_CHARSET &&
IsCharLowerW(*(lpTextW + i))) {
02231
CharUpperBuffW(lpTextW + i, 1);
02232 *(LPDWORD)ch = 0;
02233
CharToOemBuffW(lpTextW + i, ch, 1);
02234
02235
02236
02237
02238
02239
OemToCharBuffW(ch, lpTextW + i,
strlen(ch));
02240
CharLowerBuffW(lpTextW + i, 1);
02241 }
else {
02242 *(LPDWORD)ch = 0;
02243
CharToOemBuffW(lpTextW + i, ch, 1);
02244
02245
02246
02247
02248
02249
OemToCharBuffW(ch, lpTextW + i,
strlen(ch));
02250 }
02251 }
02252 }
02253 }
02254
02255
02256
ECMergeUndoInsertInfo(
Pundo(ped), ped->
ichCaret, *pcchInsert);
02257
02258 ped->
ichCaret += *pcchInsert;
02259
02260
if (ped->
pLpkEditCallout) {
02261 HDC hdc;
02262
02263 hdc =
ECGetEditDC (ped,
TRUE);
02264 ped->
ichCaret = ped->
pLpkEditCallout->
EditAdjustCaret (ped, hdc, pedText, ped->
ichCaret);
02265
ECReleaseEditDC (ped, hdc,
TRUE);
02266 }
02267
02268 ped->
ichMinSel = ped->
ichMaxSel = ped->
ichCaret;
02269
02270
ECUnlock(ped);
02271
02272
02273
02274
02275 ped->
fDirty =
TRUE;
02276
02277
return TRUE;
02278 }
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293 ICH ECDeleteText(
02294
PED ped)
02295 {
02296 PSTR pedText;
02297
ICH cchDelete;
02298 LPSTR lpDeleteSaveBuffer;
02299 HANDLE hDeletedText;
02300
DWORD bufferOffset;
02301
02302 cchDelete = ped->
ichMaxSel - ped->
ichMinSel;
02303
02304
if (!cchDelete)
02305
return (0);
02306
02307
02308
02309
02310 pedText =
ECLock(ped);
02311
02312
02313
02314
02315
if (ped->undoType ==
UNDO_NONE) {
02316 UNDODELETEFROMSCRATCH:
02317
if (ped->hDeletedText =
UserGlobalAlloc(GPTR, (LONG)((cchDelete+1)*ped->
cbChar))) {
02318 ped->undoType =
UNDO_DELETE;
02319 ped->ichDeleted = ped->
ichMinSel;
02320 ped->cchDeleted = cchDelete;
02321 lpDeleteSaveBuffer = ped->hDeletedText;
02322 RtlCopyMemory(lpDeleteSaveBuffer, pedText + ped->
ichMinSel*ped->
cbChar, cchDelete*ped->
cbChar);
02323 lpDeleteSaveBuffer[cchDelete*ped->
cbChar] = 0;
02324 }
02325 }
else if (ped->undoType &
UNDO_INSERT) {
02326 UNDODELETE:
02327
ECEmptyUndo(
Pundo(ped));
02328
02329 ped->ichInsStart = ped->ichInsEnd = 0xFFFFFFFF;
02330 ped->ichDeleted = 0xFFFFFFFF;
02331 ped->cchDeleted = 0;
02332
goto UNDODELETEFROMSCRATCH;
02333 }
else if (ped->undoType ==
UNDO_DELETE) {
02334
if (ped->ichDeleted == ped->
ichMaxSel) {
02335
02336
02337
02338
02339 hDeletedText =
UserGlobalReAlloc(ped->hDeletedText, (LONG)(cchDelete + ped->cchDeleted + 1)*ped->
cbChar, GHND);
02340
if (!hDeletedText)
02341
goto UNDODELETE;
02342 bufferOffset = 0;
02343 ped->ichDeleted = ped->
ichMinSel;
02344 }
else if (ped->ichDeleted == ped->
ichMinSel) {
02345
02346
02347
02348
02349 hDeletedText =
UserGlobalReAlloc(ped->hDeletedText, (LONG)(cchDelete + ped->cchDeleted + 1)*ped->
cbChar, GHND);
02350
if (!hDeletedText)
02351
goto UNDODELETE;
02352 bufferOffset = ped->cchDeleted*ped->
cbChar;
02353 }
else {
02354
02355
02356
02357
02358
02359
goto UNDODELETE;
02360 }
02361
02362 ped->hDeletedText = hDeletedText;
02363 lpDeleteSaveBuffer = (LPSTR)hDeletedText;
02364
if (!bufferOffset) {
02365
02366
02367
02368
02369
02370 RtlMoveMemory(lpDeleteSaveBuffer + cchDelete*ped->
cbChar, lpDeleteSaveBuffer,
02371 ped->cchDeleted*ped->
cbChar);
02372 }
02373 RtlCopyMemory(lpDeleteSaveBuffer + bufferOffset, pedText + ped->
ichMinSel*ped->
cbChar,
02374 cchDelete*ped->
cbChar);
02375
02376 lpDeleteSaveBuffer[(ped->cchDeleted + cchDelete)*ped->
cbChar] = 0;
02377 ped->cchDeleted += cchDelete;
02378 }
02379
02380
if (ped->
ichMaxSel != ped->
cch) {
02381
02382
02383
02384
02385
02386 RtlMoveMemory(pedText + ped->
ichMinSel*ped->
cbChar, pedText + ped->
ichMaxSel*ped->
cbChar,
02387 (ped->
cch - ped->
ichMaxSel)*ped->
cbChar);
02388 }
02389
02390
if (ped->
cchAlloc - ped->
cch >
CCHALLOCEXTRA) {
02391
02392
02393
02394
02395
LOCALREALLOC(ped->
hText, (
DWORD)(ped->
cch + (
CCHALLOCEXTRA / 2))*ped->
cbChar,
LHND, ped->
hInstance,
NULL);
02396 ped->
cchAlloc =
LOCALSIZE(ped->
hText, ped->
hInstance) / ped->
cbChar;
02397 }
02398
02399 ped->
cch -= cchDelete;
02400
02401
if (ped->
pLpkEditCallout) {
02402 HDC hdc;
02403
02404 hdc =
ECGetEditDC (ped,
TRUE);
02405 ped->
ichMinSel = ped->
pLpkEditCallout->
EditAdjustCaret (ped, hdc, pedText, ped->
ichMinSel);
02406
ECReleaseEditDC (ped, hdc,
TRUE);
02407 }
02408
02409 ped->
ichCaret = ped->
ichMaxSel = ped->
ichMinSel;
02410
02411
ECUnlock(ped);
02412
02413
02414
02415
02416 ped->
fDirty =
TRUE;
02417
02418
return (cchDelete);
02419 }
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429 void ECNotifyParent(
02430
PED ped,
02431
int notificationCode)
02432 {
02433
02434
02435
02436
02437
02438
02439
SendMessage(ped->
hwndParent, WM_COMMAND,
02440 (
DWORD)MAKELONG(
PTR_TO_ID(ped->
pwnd->
spmenu), notificationCode),
02441 (LPARAM)ped->
hwnd);
02442 }
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452 void ECSetEditClip(
PED ped, HDC hdc, BOOL fLeftMargin)
02453 {
02454 RECT rcClient;
02455 RECT rcClip;
02456
02457
CopyRect(&rcClip, &ped->
rcFmt);
02458
02459
if (ped->
pLpkEditCallout) {
02460
02461 rcClip.left -= ped->
wLeftMargin;
02462 rcClip.right += ped->
wRightMargin;
02463 }
else {
02464
if (fLeftMargin)
02465 rcClip.left -= ped->
wLeftMargin;
02466
if (ped->
fWrap)
02467 rcClip.right += ped->
wRightMargin;
02468 }
02469
02470
02471
02472
_GetClientRect(ped->
pwnd, &rcClient);
02473
if (ped->
fFlatBorder)
02474
InflateRect(&rcClient, -
SYSMET(CXBORDER), -
SYSMET(CYBORDER));
02475
02476
IntersectRect(&rcClient, &rcClient, &rcClip);
02477 IntersectClipRect(hdc,rcClient.left, rcClient.top,
02478 rcClient.right, rcClient.bottom);
02479 }
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492 HDC
ECGetEditDC(
02493
PED ped,
02494 BOOL fFastDC )
02495 {
02496 HDC hdc;
02497
02498
if (!fFastDC)
02499
NtUserHideCaret(ped->
hwnd);
02500
02501
if ( hdc =
NtUserGetDC(ped->
hwnd) ) {
02502
ECSetEditClip(ped, hdc, (
BOOL)(ped->
xOffset == 0));
02503
02504
02505
02506
02507
if (ped->
hFont)
02508 SelectObject(hdc, ped->
hFont);
02509 }
02510
02511
return hdc;
02512 }
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524 void ECReleaseEditDC(
02525
PED ped,
02526 HDC hdc,
02527 BOOL fFastDC)
02528 {
02529
02530
02531
02532
02533
ReleaseDC(ped->
hwnd, hdc);
02534
02535
if (!fFastDC)
02536
NtUserShowCaret(ped->
hwnd);
02537 }
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547 void ECResetTextInfo(
PED ped)
02548 {
02549
02550
02551
02552 ped->
iCaretLine = ped->
ichCaret = 0;
02553 ped->
ichMinSel = ped->
ichMaxSel = 0;
02554 ped->
xOffset = ped->
ichScreenStart = 0;
02555 ped->
fDirty =
FALSE;
02556
02557
ECEmptyUndo(
Pundo(ped));
02558
02559
if (ped->
fSingle) {
02560
if (!ped->
listboxHwnd)
02561
ECNotifyParent(ped, EN_UPDATE);
02562 }
else {
02563
#ifdef BOGUS
02564
02565
02566
02567
MLStripCrCrLf(ped);
02568
#endif
02569
MLBuildchLines(ped, 0, 0,
FALSE,
NULL,
NULL);
02570 }
02571
02572
if (
_IsWindowVisible(ped->
pwnd)) {
02573
BOOL fErase;
02574
02575
if (ped->
fSingle)
02576 fErase =
FALSE;
02577
else
02578 fErase = ((ped->
ichLinesOnScreen + ped->
ichScreenStart) >= ped->
cLines);
02579
02580
02581
02582
ECInvalidateClient(ped, fErase);
02583
02584
02585
02586
02587
02588
if (!ped->
fWin31Compat)
02589
UpdateWindow(ped->
hwnd);
02590 }
02591
02592
if (ped->
fSingle && !ped->
listboxHwnd)
02593
ECNotifyParent(ped, EN_CHANGE);
02594
02595
if (
FWINABLE()) {
02596
NotifyWinEvent(EVENT_OBJECT_VALUECHANGE,
HW(ped->
pwnd), OBJID_CLIENT,
02597 INDEXID_CONTAINER);
02598 }
02599 }
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612 BOOL ECSetText(
02613
PED ped,
02614 LPSTR lpstr)
02615 {
02616
ICH cchLength;
02617
ICH cchSave = ped->
cch;
02618
ICH ichCaretSave = ped->
ichCaret;
02619 HWND hwndSave = ped->
hwnd;
02620 HANDLE hText;
02621
02622 ped->
cch = ped->
ichCaret = 0;
02623
02624 ped->
cchAlloc =
LOCALSIZE(ped->
hText, ped->
hInstance) / ped->
cbChar;
02625
if (!lpstr) {
02626 hText =
LOCALREALLOC(ped->
hText,
CCHALLOCEXTRA*ped->
cbChar,
LHND, ped->
hInstance, &lpstr);
02627
if (hText !=
NULL) {
02628 ped->
hText = hText;
02629 }
else {
02630
return FALSE;
02631 }
02632 }
else {
02633 cchLength =
StringLength(lpstr, ped->
fAnsi);
02634
02635
#ifdef NEVER
02636
02637
02638
if (ped->
fSingle) {
02639
02640
02641
02642 cchLength =
min(cchLength, (
ICH)(0x7FFD/ped->
cbChar));
02643 }
02644
#endif
02645
02646
02647
02648
02649
if (cchLength && !
ECInsertText(ped, lpstr, &cchLength)) {
02650
02651
02652
02653
02654 ped->
cch = cchSave;
02655 ped->
ichCaret = ichCaretSave;
02656
ECNotifyParent(ped, EN_ERRSPACE);
02657
return FALSE;
02658 }
02659 }
02660
02661 ped->
cchAlloc =
LOCALSIZE(ped->
hText, ped->
hInstance) / ped->
cbChar;
02662
02663
if (
IsWindow(hwndSave))
02664
ECResetTextInfo(ped);
02665
02666
return TRUE;
02667 }
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679 void ECInvalidateClient(
PED ped, BOOL fErase)
02680 {
02681
if (ped->
fFlatBorder) {
02682 RECT rcT;
02683
02684
_GetClientRect(ped->
pwnd, &rcT);
02685
InflateRect(&rcT, -
SYSMET(CXBORDER),
02686 -
SYSMET(CYBORDER));
02687
NtUserInvalidateRect(ped->
hwnd, &rcT, fErase);
02688 }
else {
02689
NtUserInvalidateRect(ped->
hwnd,
NULL, fErase);
02690 }
02691 }
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703 ICH ECCopy(
02704
PED ped)
02705 {
02706 HANDLE hData;
02707
char *pchSel;
02708
char FAR *lpchClip;
02709
ICH cbData;
02710
02711
02712
02713
02714
if (ped->
charPasswordChar) {
02715
NtUserMessageBeep(0);
02716
return 0;
02717 }
02718
02719 cbData = (ped->
ichMaxSel - ped->
ichMinSel) * ped->
cbChar;
02720
02721
if (!cbData)
02722
return 0;
02723
02724
if (!
OpenClipboard(ped->
hwnd))
02725
return 0;
02726
02727
NtUserEmptyClipboard();
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
if (
GetClientInfo()->CI_flags &
CI_16BIT) {
02742
pfnWowEmptyClipBoard();
02743 }
02744
02745
02746
02747
02748
02749
if (!(hData =
UserGlobalAlloc(
LHND, (LONG)(cbData + ped->
cbChar)))) {
02750
NtUserCloseClipboard();
02751
return (0);
02752 }
02753
02754
USERGLOBALLOCK(hData, lpchClip);
02755 UserAssert(lpchClip);
02756 pchSel =
ECLock(ped);
02757 pchSel = pchSel + (ped->
ichMinSel * ped->
cbChar);
02758
02759 RtlCopyMemory(lpchClip, pchSel, cbData);
02760
02761
if (ped->
fAnsi)
02762 *(lpchClip + cbData) = 0;
02763
else
02764 *(LPWSTR)(lpchClip + cbData) = (WCHAR)0;
02765
02766
ECUnlock(ped);
02767
USERGLOBALUNLOCK(hData);
02768
02769
SetClipboardData( ped->
fAnsi ? CF_TEXT : CF_UNICODETEXT, hData);
02770
02771
NtUserCloseClipboard();
02772
02773
return (cbData);
02774 }
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787 LRESULT
EditWndProcA(
02788 HWND hwnd,
02789 UINT message,
02790 WPARAM wParam,
02791 LPARAM lParam)
02792 {
02793
PWND pwnd;
02794
02795
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL)
02796
return 0;
02797
02798
02799
02800
02801
02802
if (!
FWINDOWMSG(message,
FNID_EDIT))
02803
return DefWindowProcWorker(pwnd, message, wParam, lParam,
TRUE);
02804
02805
return EditWndProcWorker(pwnd, message, wParam, lParam,
TRUE);
02806 }
02807
02808 LRESULT
EditWndProcW(
02809 HWND hwnd,
02810 UINT message,
02811 WPARAM wParam,
02812 LPARAM lParam)
02813 {
02814
PWND pwnd;
02815
02816
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL)
02817
return 0;
02818
02819
02820
02821
02822
02823
if (!
FWINDOWMSG(message,
FNID_EDIT)) {
02824
return DefWindowProcWorker(pwnd, message, wParam, lParam,
FALSE);
02825 }
02826
02827
return EditWndProcWorker(pwnd, message, wParam, lParam,
FALSE);
02828 }
02829
02830
02831 LRESULT
EditWndProcWorker(
02832
PWND pwnd,
02833 UINT message,
02834 WPARAM wParam,
02835 LPARAM lParam,
02836 DWORD fAnsi)
02837 {
02838
PED ped;
02839 HWND hwnd =
HWq(pwnd);
02840
static BOOL fInit =
TRUE;
02841
02842
VALIDATECLASSANDSIZE(pwnd,
FNID_EDIT);
02843
INITCONTROLLOOKASIDE(&
EditLookaside,
ED, pwnd, 4);
02844
02845
02846
02847
02848
02849
02850 ped = ((
PEDITWND)pwnd)->ped;
02851
02852
02853
02854
02855
if (!ped->
fInitialized) {
02856 ped->
fInitialized =
TRUE;
02857 ped->
fAnsi =
TestWF(pwnd,
WFANSICREATOR) ?
TRUE :
FALSE;
02858 }
02859
02860
02861
02862
02863
02864
02865
if (ped->
fAnsi == fAnsi ||
02866 (message >= WM_USER) ||
02867 !
MessageTable[message].
bThunkMessage) {
02868
return EditWndProc(pwnd, message, wParam, lParam);
02869 }
02870
02871
return CsSendMessage(hwnd, message, wParam, lParam,
02872 fAnsi ? (ULONG_PTR)
EditWndProcW : (ULONG_PTR)
EditWndProcA,
02873
FNID_CALLWINDOWPROC, fAnsi);
02874 }
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904 LRESULT
EditWndProc(
02905
PWND pwnd,
02906 UINT message,
02907 WPARAM wParam,
02908 LPARAM lParam)
02909 {
02910 HWND hwnd =
HWq(pwnd);
02911 LRESULT lreturn;
02912
PED ped;
02913
02914
02915
02916
02917
02918
02919 ped = ((
PEDITWND)pwnd)->ped;
02920
02921
02922
02923
02924 lreturn = 1
L;
02925
switch (message) {
02926
02927
02928
02929
02930
02931
case WM_KEYDOWN:
02932
02933
if (ped && ped->
pLpkEditCallout && ped->
fAllowRTL) {
02934
02935 ped->
fSwapRoOnUp =
FALSE;
02936
02937
switch (wParam) {
02938
case VK_SHIFT:
02939
if ((
GetKeyState(VK_CONTROL) & 0x8000) && !(
GetKeyState(VK_MENU) & 0x8000)) {
02940
02941
02942
if (
MapVirtualKey((LONG)lParam>>16&0xff, 3) == VK_LSHIFT) {
02943
02944 ped->
fSwapRoOnUp = (ped->
fRtoLReading) || (ped->
format & ES_RIGHT) ;
02945 ped->
fLShift =
TRUE;
02946 }
else {
02947
02948 ped->
fSwapRoOnUp = (!ped->
fRtoLReading) || (ped->
format & ES_RIGHT);
02949 ped->
fLShift =
FALSE;
02950 }
02951 }
02952
break;
02953
02954
case VK_LEFT:
02955
if (ped->
fRtoLReading) {
02956 wParam = VK_RIGHT;
02957 }
02958
break;
02959
02960
case VK_RIGHT:
02961
if (ped->
fRtoLReading) {
02962 wParam = VK_LEFT;
02963 }
02964
break;
02965 }
02966 }
02967
goto HandleEditMsg;
02968
02969
case WM_KEYUP:
02970
if (ped && ped->
pLpkEditCallout && ped->
fAllowRTL && ped->
fSwapRoOnUp) {
02971
02972
BOOL fReadingOrder;
02973
02974
02975 ped->
fSwapRoOnUp =
FALSE;
02976 fReadingOrder = ped->
fRtoLReading;
02977
02978
02979 SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~ES_FMTMASK);
02980
02981
if (ped->
fLShift) {
02982
02983 SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE)
02984 & ~(WS_EX_RTLREADING | WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR));
02985
02986
02987
ECNotifyParent(ped, EN_ALIGN_LTR_EC);
02988
02989 }
else {
02990
02991 SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE)
02992 | WS_EX_RTLREADING | WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR);
02993
02994
02995
ECNotifyParent(ped, EN_ALIGN_RTL_EC);
02996
02997 }
02998
02999
03000
if (fReadingOrder == (
BOOL) ped->
fRtoLReading) {
03001
ECInvalidateClient(ped,
TRUE);
03002 }
03003 }
03004
goto HandleEditMsg;
03005
03006
case WM_INPUTLANGCHANGE:
03007
if (ped) {
03008
03009 HKL hkl =
THREAD_HKL();
03010
03011
ECInitInsert(ped, hkl);
03012
03013
if (ped->
fInReconversion) {
03014
ECInOutReconversionMode(ped,
FALSE);
03015 }
03016
03017
03018
03019
03020
03021
03022
if (ped->
fFocus &&
fpImmIsIME(hkl)) {
03023 POINT pt;
03024
03025
ECImmSetCompositionFont(ped);
03026
NtUserGetCaretPos(&pt);
03027
ECImmSetCompositionWindow(ped, pt.x, pt.y);
03028 }
03029 }
03030
03031
goto HandleEditMsg;
03032
03033
case WM_COPY:
03034
03035
03036
03037
03038
03039 lreturn = (LONG)
ECCopy(ped);
03040
break;
03041
03042
case WM_CUT:
03043
03044
03045
03046
03047
03048
ECCutText(ped);
03049
return 0;
03050
03051
case WM_CLEAR:
03052
03053
03054
03055
03056
ECClearText(ped);
03057
return 0;
03058
03059
case WM_ENABLE:
03060
03061
03062
03063
03064
03065 lreturn = (LONG)(ped->
fDisabled = !((
BOOL)wParam));
03066
ECInvalidateClient(ped,
TRUE);
03067
break;
03068
03069
case WM_SYSCHAR:
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
if ((lParam &
SYS_ALTERNATE) && ((WORD)wParam == VK_BACK))
03080
return TRUE;
03081
else {
03082
return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->
fAnsi);
03083 }
03084
break;
03085
03086
case EM_GETLINECOUNT:
03087
03088
03089
03090
03091
03092 lreturn = (LONG)ped->
cLines;
03093
break;
03094
03095
case EM_GETMODIFY:
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105 lreturn = (LONG)ped->
fDirty;
03106
break;
03107
03108
case EM_SETMODIFY:
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118 ped->
fDirty = (wParam != 0);
03119
break;
03120
03121
case EM_GETRECT:
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
CopyRect((LPRECT)lParam, (LPRECT)&ped->
rcFmt);
03132 lreturn = (LONG)
TRUE;
03133
break;
03134
03135
case WM_GETFONT:
03136
03137
03138
03139
03140
03141 lreturn = (LRESULT)ped->
hFont;
03142
break;
03143
03144
case WM_SETFONT:
03145
03146
03147
03148
03149
03150
ECSetFont(ped, (HANDLE)wParam, (
BOOL)LOWORD(lParam));
03151
break;
03152
03153
case WM_GETTEXT:
03154
03155
03156
03157
03158
03159 lreturn = (LRESULT)
ECGetText(ped, (
ICH)wParam, (LPSTR)lParam,
TRUE);
03160
break;
03161
03162
case WM_SETTEXT:
03163
03164
03165
03166
03167 lreturn = (LRESULT)
ECSetText(ped, (LPSTR)lParam);
03168
break;
03169
03170
case WM_GETTEXTLENGTH:
03171
03172
03173
03174
03175 lreturn = (LONG)ped->
cch;
03176
break;
03177
03178
case WM_NCDESTROY:
03179
case WM_FINALDESTROY:
03180
03181
03182
03183
03184
03185
ECNcDestroyHandler(pwnd, ped);
03186
return 0;
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
case WM_RBUTTONDOWN:
03202 ped->
fSawRButtonDown =
TRUE;
03203
goto HandleEditMsg;
03204
03205
case WM_RBUTTONUP:
03206
if (ped->
fSawRButtonDown) {
03207 ped->
fSawRButtonDown =
FALSE;
03208
if (!ped->
fInReconversion) {
03209
goto HandleEditMsg;
03210 }
03211 }
03212
03213
return 0;
03214
03215
case WM_CONTEXTMENU: {
03216 POINT pt ;
03217
int nHit =
FindNCHit(pwnd, (LONG)lParam);
03218
if ((nHit == HTVSCROLL) || (nHit == HTHSCROLL)) {
03219
return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->
fAnsi);
03220 }
03221 POINTSTOPOINT(pt, lParam);
03222
if (!
TestWF(pwnd,
WFOLDUI) &&
ECIsAncestorActive(hwnd))
03223
ECMenu(hwnd, ped, &pt);
03224 }
03225
return 0;
03226
03227
case EM_CANUNDO:
03228
03229
03230
03231
03232
03233 lreturn = (LONG)(ped->undoType !=
UNDO_NONE);
03234
break;
03235
03236
case EM_EMPTYUNDOBUFFER:
03237
03238
03239
03240
03241
03242
ECEmptyUndo(
Pundo(ped));
03243
break;
03244
03245
case EM_GETMARGINS:
03246
03247
03248
03249
03250
return(MAKELONG(ped->
wLeftMargin, ped->
wRightMargin));
03251
03252
case EM_SETMARGINS:
03253
03254
03255
03256
03257
ECSetMargin(ped, (
UINT)wParam, (
DWORD)lParam,
TRUE);
03258
return 0;
03259
03260
case EM_GETSEL:
03261
03262
03263
03264
03265
03266
03267
03268
if ((PDWORD)wParam !=
NULL) {
03269 *((PDWORD)wParam) = ped->
ichMinSel;
03270 }
03271
if ((PDWORD)lParam !=
NULL) {
03272 *((PDWORD)lParam) = ped->
ichMaxSel;
03273 }
03274 lreturn = MAKELONG(ped->
ichMinSel,ped->
ichMaxSel);
03275
break;
03276
03277
case EM_GETLIMITTEXT:
03278
03279
03280
03281
03282
return(ped->
cchTextMax);
03283
03284
case EM_SETLIMITTEXT:
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
if (ped->
fSingle) {
03295
if (wParam) {
03296 wParam =
min(0x7FFFFFFEu, wParam);
03297 }
else {
03298 wParam = 0x7FFFFFFEu;
03299 }
03300 }
03301
03302
if (wParam) {
03303 ped->
cchTextMax = (
ICH)wParam;
03304 }
else {
03305 ped->
cchTextMax = 0xFFFFFFFFu;
03306 }
03307
break;
03308
03309
case EM_POSFROMCHAR:
03310
03311
03312
03313
if (wParam >= ped->
cch) {
03314
return(-1
L);
03315 }
03316
goto HandleEditMsg;
03317
03318
case EM_CHARFROMPOS: {
03319
03320 RECT rc;
03321 POINT pt;
03322
03323 POINTSTOPOINT(pt, lParam);
03324
_GetClientRect(pwnd, &rc);
03325
if (!
PtInRect(&rc, pt)) {
03326
return(-1
L);
03327 }
03328
goto HandleEditMsg;
03329 }
03330
03331
case EM_SETPASSWORDCHAR:
03332
03333
03334
03335
03336
03337
ECSetPasswordChar(ped, (
UINT)wParam);
03338
break;
03339
03340
case EM_GETPASSWORDCHAR:
03341 lreturn = (
DWORD)ped->
charPasswordChar;
03342
break;
03343
03344
case EM_SETREADONLY:
03345
03346
03347
03348
03349 ped->
fReadOnly = (wParam != 0);
03350
if (wParam)
03351
SetWindowState(pwnd,
EFREADONLY);
03352
else
03353
ClearWindowState(pwnd,
EFREADONLY);
03354 lreturn = 1
L;
03355
03356
ECEnableDisableIME( ped );
03357
03358
03359
03360
ECInvalidateClient(ped,
TRUE);
03361
break;
03362
03363
case EM_SETWORDBREAKPROC:
03364
03365
03366
03367
03368
03369 ped->
lpfnNextWord = (EDITWORDBREAKPROCA)lParam;
03370
break;
03371
03372
case EM_GETWORDBREAKPROC:
03373 lreturn = (LRESULT)ped->
lpfnNextWord;
03374
break;
03375
03376
03377
case EM_GETIMESTATUS:
03378
03379
switch (wParam) {
03380
case EMSIS_COMPOSITIONSTRING:
03381
return ped->
wImeStatus;
03382
#if 0 // memphis
03383
case EMSIS_GETLBBIT:
03384
return (
DWORD)ped->bLBBit;
03385
#endif
03386
}
03387
break;
03388
03389
case EM_SETIMESTATUS:
03390
03391
switch (wParam) {
03392
case EMSIS_COMPOSITIONSTRING:
03393 ped->
wImeStatus = (WORD)lParam;
03394 }
03395
break;
03396
03397
03398
case WM_NCCREATE:
03399 lreturn =
ECNcCreate(ped, pwnd, (LPCREATESTRUCT)lParam);
03400
break;
03401
03402
case WM_LBUTTONDOWN:
03403
03404
03405
03406
03407
03408
03409
03410
if (
ECIsAncestorActive(hwnd)) {
03411
03412
03413
03414
03415
if (ped->
fInReconversion || ped->
fKorea) {
03416 BOOLEAN fReconversion = (BOOLEAN)ped->
fInReconversion;
03417
DWORD dwIndex = fReconversion ? CPS_CANCEL : CPS_COMPLETE;
03418 HIMC hImc;
03419
03420 ped->
fReplaceCompChr =
FALSE;
03421
03422 hImc =
fpImmGetContext(ped->
hwnd);
03423
if (hImc) {
03424
fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, dwIndex, 0);
03425
fpImmReleaseContext(ped->
hwnd, hImc);
03426 }
03427
03428
if (fReconversion) {
03429
ECInOutReconversionMode(ped,
FALSE);
03430 }
03431
03432
ECSetCaretHandler(ped);
03433 }
03434
03435
goto HandleEditMsg;
03436 }
03437
break;
03438
03439
case WM_MOUSEMOVE:
03440
03441
03442
03443
if (ped->
fMouseDown)
03444
goto HandleEditMsg;
03445
break;
03446
03447
case WM_IME_SETCONTEXT:
03448
03449
03450
03451
03452
if ( ped->
fInsertCompChr ) {
03453 lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
03454 }
03455
03456
if ( wParam ) {
03457
03458 PINPUTCONTEXT pInputContext;
03459 HIMC hImc;
03460
03461 hImc =
fpImmGetContext( hwnd );
03462
if ( (pInputContext =
fpImmLockIMC( hImc )) !=
NULL ) {
03463 pInputContext->fdw31Compat &= ~F31COMPAT_ECSETCFS;
03464
fpImmUnlockIMC( hImc );
03465 }
03466
if (
GetClientInfo()->CI_flags &
CI_16BIT) {
03467
fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0
L);
03468 }
03469
fpImmReleaseContext( hwnd, hImc );
03470 }
03471
return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->
fAnsi);
03472
03473
case WM_IME_ENDCOMPOSITION:
03474
ECInOutReconversionMode(ped,
FALSE);
03475
03476
if (ped->
fReplaceCompChr) {
03477
ICH ich;
03478 HDC hdc;
03479
03480
03481
03482
03483 ich = (ped->
fAnsi) ? 2 : 1;
03484 ped->
fReplaceCompChr =
FALSE;
03485 ped->
ichMaxSel =
min(ped->
ichCaret + ich, ped->
cch);
03486 ped->
ichMinSel = ped->
ichCaret;
03487
if (ped->
fSingle) {
03488
if (
ECDeleteText( ped ) > 0) {
03489
03490
03491
03492
ECNotifyParent(ped, EN_UPDATE);
03493 hdc =
ECGetEditDC(ped,
FALSE);
03494
SLDrawText(ped, hdc, 0);
03495
ECReleaseEditDC(ped, hdc,
FALSE);
03496
03497
03498
03499
ECNotifyParent(ped, EN_CHANGE);
03500 }
03501 }
03502
else {
03503
MLDeleteText(ped);
03504 }
03505
03506
ECSetCaretHandler( ped );
03507 }
03508
return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->
fAnsi);
03509
03510
case WM_IME_STARTCOMPOSITION:
03511
if ( ped->
fInsertCompChr ) {
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
break;
03524
03525 }
else {
03526
return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->
fAnsi);
03527 }
03528
03529
03530
case WM_IME_COMPOSITION:
03531
return ECImeComposition(ped, wParam, lParam);
03532
03533
case WM_KILLFOCUS:
03534
03535
03536
03537
03538
if (ped &&
fpImmIsIME(
THREAD_HKL())) {
03539 HIMC hImc =
fpImmGetContext(hwnd);
03540
03541
if (hImc !=
NULL_HIMC) {
03542
if (ped->
fReplaceCompChr || (ped->
wImeStatus & EIMES_COMPLETECOMPSTRKILLFOCUS)) {
03543
03544
03545
fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
03546 }
else if (ped->
fInReconversion) {
03547
03548
03549
fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
03550 }
03551
03552
03553
if (ped->
fInReconversion) {
03554
ECInOutReconversionMode(ped,
FALSE);
03555 }
03556
03557
fpImmReleaseContext(hwnd, hImc);
03558 }
03559 }
03560
goto HandleEditMsg;
03561
break;
03562
03563
case WM_SETFOCUS:
03564
if (ped && !ped->
fFocus) {
03565 HKL hkl =
THREAD_HKL();
03566
03567
if (
fpImmIsIME(hkl)) {
03568 HIMC hImc;
03569
03570 hImc =
fpImmGetContext(hwnd);
03571
if (hImc) {
03572 LPINPUTCONTEXT lpImc;
03573
03574
if (ped->
wImeStatus & EIMES_CANCELCOMPSTRINFOCUS) {
03575
03576
fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
03577 }
03578
03579
ECImmSetCompositionFont(ped);
03580
03581
if ((lpImc =
fpImmLockIMC(hImc)) !=
NULL) {
03582
03583
03584
03585
03586
03587 lpImc->fdw31Compat |= F31COMPAT_ECSETCFS;
03588
03589
fpImmUnlockIMC(hImc);
03590 }
03591
fpImmReleaseContext(hwnd, hImc);
03592 }
03593
03594
03595
03596
03597
03598 ped->
ptScreenBounding.x = -1;
03599 ped->
ptScreenBounding.y = -1;
03600 }
03601
ECInitInsert(ped, hkl);
03602 }
03603
goto HandleEditMsg;
03604
break;
03605
03606
case WM_IME_REQUEST:
03607
03608
return EcImeRequestHandler(ped, wParam, lParam);
03609
03610
case WM_CREATE:
03611
if (ped)
03612
ECEnableDisableIME(ped);
03613
goto HandleEditMsg;
03614
break;
03615
03616
default:
03617 HandleEditMsg:
03618
03619
03620
03621
03622
03623
if (ped !=
NULL) {
03624
if (ped->
fSingle) {
03625 lreturn =
SLEditWndProc(hwnd, ped, message, wParam, lParam);
03626 }
else {
03627 lreturn =
MLEditWndProc(hwnd, ped, message, wParam, lParam);
03628 }
03629 }
03630 }
03631
03632
return lreturn;
03633 }
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652 void ECFindXORblks(
03653
LPBLOCK lpOldBlk,
03654
LPBLOCK lpNewBlk,
03655
LPBLOCK lpBlk1,
03656
LPBLOCK lpBlk2)
03657 {
03658
if (lpOldBlk->
StPos >= lpNewBlk->
StPos) {
03659 lpBlk1->
StPos = lpNewBlk->
StPos;
03660 lpBlk1->
EndPos =
min(lpOldBlk->
StPos, lpNewBlk->
EndPos);
03661 }
else {
03662 lpBlk1->
StPos = lpOldBlk->
StPos;
03663 lpBlk1->
EndPos =
min(lpNewBlk->
StPos, lpOldBlk->
EndPos);
03664 }
03665
03666
if (lpOldBlk->
EndPos <= lpNewBlk->
EndPos) {
03667 lpBlk2->
StPos =
max(lpOldBlk->
EndPos, lpNewBlk->
StPos);
03668 lpBlk2->
EndPos = lpNewBlk->
EndPos;
03669 }
else {
03670 lpBlk2->
StPos =
max(lpNewBlk->
EndPos, lpOldBlk->
StPos);
03671 lpBlk2->
EndPos = lpOldBlk->
EndPos;
03672 }
03673 }
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692 BOOL ECCalcChangeSelection(
03693
PED ped,
03694 ICH ichOldMinSel,
03695 ICH ichOldMaxSel,
03696
LPBLOCK OldBlk,
03697
LPBLOCK NewBlk)
03698 {
03699
BLOCK Blk[2];
03700
int iBlkCount = 0;
03701
03702 Blk[0].
StPos = Blk[0].
EndPos = Blk[1].
StPos = Blk[1].
EndPos = 0xFFFFFFFF;
03703
03704
03705
03706
03707
if (ichOldMinSel != ichOldMaxSel) {
03708
03709
03710
03711
03712 Blk[0].
StPos = OldBlk->
StPos;
03713 Blk[0].
EndPos = OldBlk->
EndPos;
03714 iBlkCount++;
03715 }
03716
03717
03718
03719
03720
if (ped->
ichMinSel != ped->
ichMaxSel) {
03721
03722
03723
03724
03725 Blk[1].
StPos = NewBlk->
StPos;
03726 Blk[1].
EndPos = NewBlk->
EndPos;
03727 iBlkCount++;
03728 }
03729
03730
03731
03732
03733
if (iBlkCount == 2) {
03734
03735
03736
03737
03738
if (ichOldMinSel == ped->
ichMinSel) {
03739
03740
03741
03742
03743
if (ichOldMaxSel == ped->
ichMaxSel)
03744
return FALSE;
03745
03746 Blk[0].
StPos =
min(NewBlk -> EndPos, OldBlk -> EndPos);
03747 Blk[0].
EndPos =
max(NewBlk -> EndPos, OldBlk -> EndPos);
03748 Blk[1].
StPos = 0xFFFFFFFF;
03749 }
else {
03750
if (ichOldMaxSel == ped->
ichMaxSel) {
03751 Blk[0].
StPos =
min(NewBlk->
StPos, OldBlk->
StPos);
03752 Blk[0].
EndPos =
max(NewBlk->
StPos, OldBlk->
StPos);
03753 Blk[1].
StPos = 0xFFFFFFFF;
03754 }
else {
03755
ECFindXORblks(OldBlk, NewBlk, &Blk[0], &Blk[1]);
03756 }
03757 }
03758 }
03759
03760 RtlCopyMemory(OldBlk, &Blk[0],
sizeof(
BLOCK));
03761 RtlCopyMemory(NewBlk, &Blk[1],
sizeof(
BLOCK));
03762
03763
return TRUE;
03764 }
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776 HBRUSH
ECGetControlBrush(
03777
PED ped,
03778 HDC hdc,
03779 LONG message)
03780 {
03781
PWND pwndSend;
03782
PWND pwndEdit;
03783
03784 pwndEdit =
ValidateHwnd(ped->
hwnd);
03785
03786
if (pwndEdit == (
PWND)
NULL)
03787
return (HBRUSH)0;
03788
03789
if ((pwndSend = (
TestwndPopup(pwndEdit) ? pwndEdit->
spwndOwner : pwndEdit->
spwndParent)) ==
NULL)
03790 pwndSend = pwndEdit;
03791
else
03792 pwndSend =
REBASEPTR(pwndEdit, pwndSend);
03793
03794 UserAssert(pwndSend);
03795
03796
if (
PtiCurrent() !=
GETPTI(pwndSend)) {
03797
return (HBRUSH)
DefWindowProcWorker(pwndSend, message,
03798 (WPARAM)hdc, (LPARAM)pwndEdit, ped->
fAnsi);
03799 }
03800
03801
03802
03803
03804
03805
return (HBRUSH)
SendMessageWorker(pwndSend, message, (WPARAM)hdc,
03806 (LPARAM)ped->
hwnd, ped->
fAnsi);
03807 }
03808
03809
UINT WINAPI
QueryFontAssocStatus(
void);
03810 UINT fFontAssocStatus = 0xffff;
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820 int ECGetDBCSVector(
PED ped, HDC hdc, BYTE CharSet)
03821 {
03822
BOOL bDBCSCodePage =
FALSE;
03823
03824
03825
03826
if (CharSet == DEFAULT_CHARSET) {
03827 CharSet = (
BYTE)GetTextCharset(hdc);
03828
03829
03830
03831
03832
03833
if (CharSet == DEFAULT_CHARSET) {
03834 CharSet = (
BYTE)
GetACPCharSet();
03835 }
03836 }
03837
03838
switch (CharSet) {
03839
case SHIFTJIS_CHARSET:
03840
case HANGEUL_CHARSET:
03841
case CHINESEBIG5_CHARSET:
03842
case GB2312_CHARSET:
03843 bDBCSCodePage =
TRUE;
03844
break;
03845
03846
case ANSI_CHARSET:
03847
case SYMBOL_CHARSET:
03848
case OEM_CHARSET:
03849
if (
fFontAssocStatus == 0xffff)
03850
fFontAssocStatus =
QueryFontAssocStatus();
03851
03852
if ((((CharSet + 2) & 0xf) &
fFontAssocStatus)) {
03853 bDBCSCodePage =
TRUE;
03854
03855
03856
03857
03858 CharSet = (
BYTE)
GetACPCharSet();
03859 }
else {
03860 bDBCSCodePage =
FALSE;
03861 }
03862
break;
03863
03864
default:
03865 bDBCSCodePage =
FALSE;
03866 }
03867
03868
if (bDBCSCodePage) {
03869 CHARSETINFO CharsetInfo;
03870
DWORD CodePage;
03871 CPINFO CPInfo;
03872
int lbIX;
03873
03874
if (TranslateCharsetInfo((
DWORD *)CharSet, &CharsetInfo, TCI_SRCCHARSET)) {
03875 CodePage = CharsetInfo.ciACP;
03876 }
else {
03877 CodePage = CP_ACP;
03878 }
03879
03880 GetCPInfo(CodePage, &CPInfo);
03881
for (lbIX=0 ; CPInfo.LeadByte[lbIX] != 0 ; lbIX+=2) {
03882 ped->
DBCSVector[lbIX ] = CPInfo.LeadByte[lbIX];
03883 ped->
DBCSVector[lbIX+1] = CPInfo.LeadByte[lbIX+1];
03884 }
03885 ped->
DBCSVector[lbIX ] = 0x0;
03886 ped->
DBCSVector[lbIX+1] = 0x0;
03887 }
else {
03888 ped->
DBCSVector[0] = 0x0;
03889 ped->
DBCSVector[1] = 0x0;
03890 }
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
if (!ped->
fAnsi) {
03907 FONTSIGNATURE fontSig;
03908
03909 GetTextCharsetInfo(hdc, &fontSig, 0);
03910
if (fontSig.fsCsb[0] &
FAREAST_CHARSET_BITS) {
03911 bDBCSCodePage =
TRUE;
03912
03913 }
03914 }
03915
03916
return bDBCSCodePage;
03917 }
03918
03919
03920
03921
03922
03923
03924
03925
03926 LPSTR
ECAnsiNext(
PED ped, LPSTR lpCurrent)
03927 {
03928
return lpCurrent+((
ECIsDBCSLeadByte(ped,*lpCurrent)==
TRUE) ? 2 : 1);
03929 }
03930
03931
03932
03933
03934
03935
03936
03937
03938 LPSTR
ECAnsiPrev(
PED ped, LPSTR lpBase, LPSTR lpStr )
03939 {
03940 LPSTR lpCurrent = lpStr -1;
03941
03942
if (!ped->
fDBCS)
03943
return lpCurrent;
03944
03945
if (lpBase >= lpCurrent)
03946
return lpBase;
03947
03948
if (
ECIsDBCSLeadByte(ped, *lpCurrent))
03949
return (lpCurrent - 1);
03950
03951
do {
03952 lpCurrent--;
03953
if (!
ECIsDBCSLeadByte(ped, *lpCurrent)) {
03954 lpCurrent++;
03955
break;
03956 }
03957 }
while(lpCurrent != lpBase);
03958
03959
return lpStr - (((lpStr - lpCurrent) & 1) ? 1 : 2);
03960 }
03961
03962
03963
03964
03965
03966
03967
03968
03969 ICH ECNextIch(
PED ped, LPSTR pStart, ICH ichCurrent )
03970 {
03971
if (!ped->
fDBCS || !ped->
fAnsi) {
03972
03973
return (ichCurrent + 1);
03974
03975 }
else {
03976
03977
ICH ichRet;
03978 LPSTR pText;
03979
03980
if (pStart)
03981 pText = pStart + ichCurrent;
03982
else
03983 pText = (LPSTR)
ECLock(ped) + ichCurrent;
03984
03985 ichRet = ichCurrent + (
ECIsDBCSLeadByte(ped, *pText) ? 2 : 1 );
03986
03987
if (!pStart)
03988
ECUnlock(ped);
03989
03990
return (ichRet);
03991 }
03992 }
03993
03994
03995
03996
03997
03998
03999
04000
04001 ICH ECPrevIch(
PED ped, LPSTR pStart, ICH ichCurrent )
04002 {
04003 LPSTR lpCurrent;
04004 LPSTR lpStr;
04005 LPSTR lpBase;
04006
04007
#ifdef SURROGATE
04008
04009
if (ped->
fAnsi || !ped->
pLpkEditCallout)
04010
#endif
04011
if (!ped->
fDBCS || !ped->
fAnsi)
04012
if ( ichCurrent )
04013
return (ichCurrent - 1);
04014
else
04015
return (ichCurrent);
04016
04017
if (ichCurrent <= 1)
04018
return 0;
04019
04020
if (pStart)
04021 lpBase = pStart;
04022
else
04023 lpBase =
ECLock(ped);
04024
04025
#ifdef SURROGATE
04026
04027
04028
04029
if (ped->
fAnsi) {
04030
04031
04032
#endif
04033
04034 lpStr = lpBase + ichCurrent;
04035 lpCurrent = lpStr - 1;
04036
if (
ECIsDBCSLeadByte(ped,*lpCurrent)) {
04037
if (!pStart)
04038
ECUnlock(ped);
04039
return (ichCurrent - 2);
04040 }
04041
04042
do {
04043 lpCurrent--;
04044
if (!
ECIsDBCSLeadByte(ped, *lpCurrent)) {
04045 lpCurrent++;
04046
break;
04047 }
04048 }
while(lpCurrent != lpBase);
04049
04050
if (!pStart)
04051
ECUnlock(ped);
04052
return (ichCurrent - (((lpStr - lpCurrent) & 1) ? 1 : 2));
04053
04054
#ifdef SURROGATE
04055
04056 }
else {
04057
04058
04059
04060 ichCurrent--;
04061
04062
if ( (((WCHAR*)lpBase)[ichCurrent] & 0xFC00) == 0xDC00
04063 && (((WCHAR*)lpBase)[ichCurrent-1] & 0xFC00) == 0xD800) {
04064
04065 ichCurrent--;
04066 }
04067
04068
if (!pStart)
04069
ECUnlock(ped);
04070
04071
return ichCurrent;
04072 }
04073
#endif
04074
}
04075
04076
04077
04078
04079
04080
04081
04082
04083 BOOL ECIsDBCSLeadByte(
PED ped, BYTE cch)
04084 {
04085
int i;
04086
04087
if (!ped->
fDBCS || !ped->
fAnsi)
04088
return (
FALSE);
04089
04090
for (i = 0; ped->
DBCSVector[i]; i += 2) {
04091
if ((ped->
DBCSVector[i] <= cch) && (ped->
DBCSVector[i+1] >= cch))
04092
return (
TRUE);
04093 }
04094
04095
return (
FALSE);
04096 }
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109 WORD
DbcsCombine(HWND hwnd, WORD ch)
04110 {
04111 MSG
msg;
04112
int i = 10;
04113
04114
while (!PeekMessageA(&
msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)) {
04115
if (--i == 0)
04116
return 0;
04117 Sleep(1);
04118 }
04119
04120
return (WORD)ch | ((WORD)(
msg.wParam) << 8);
04121 }
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133 ICH ECAdjustIch(
PED ped, LPSTR lpstr, ICH ch )
04134 {
04135
ICH newch = ch;
04136
04137
if (!ped->
fAnsi || !ped->
fDBCS || newch == 0)
04138
return ( ch );
04139
04140
if (!
ECIsDBCSLeadByte(ped,lpstr[--newch]))
04141
return ( ch );
04142
while(1) {
04143
if (!
ECIsDBCSLeadByte(ped,lpstr[newch])) {
04144 newch++;
04145
break;
04146 }
04147
if (newch)
04148 newch--;
04149
else
04150
break;
04151 }
04152
return ((ch - newch) & 1) ? ch-1 : ch;
04153 }
04154
04155
04156
04157
04158
04159
04160
04161
04162 ICH FAR PASCAL
ECAdjustIchNext(
PED ped, LPSTR lpstr, ICH ch)
04163 {
04164
ICH ichNew =
ECAdjustIch(ped,lpstr,ch);
04165 LPSTR lpnew = lpstr+ichNew;
04166
04167
04168
if (ch > ichNew)
04169 lpnew =
ECAnsiNext(ped, lpnew);
04170
04171
return (
ICH)(lpnew-lpstr);
04172 }
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185 void ECUpdateFormat(
04186
PED ped,
04187 DWORD dwStyle,
04188 DWORD dwExStyle)
04189 {
04190
UINT fNewRtoLReading;
04191
UINT uiNewFormat;
04192
04193
04194
04195 fNewRtoLReading = dwExStyle & WS_EX_RTLREADING ? 1 : 0;
04196 uiNewFormat = dwStyle & ES_FMTMASK;
04197
04198
04199
04200
04201
if (uiNewFormat == ES_LEFT && dwExStyle & WS_EX_RIGHT) {
04202 uiNewFormat = ES_RIGHT;
04203 }
04204
04205
04206
04207
04208
04209
if (fNewRtoLReading) {
04210
switch (uiNewFormat) {
04211
case ES_LEFT: uiNewFormat = ES_RIGHT;
break;
04212
case ES_RIGHT: uiNewFormat = ES_LEFT;
break;
04213 }
04214 }
04215
04216
04217
04218
04219 ped->
format = uiNewFormat;
04220
04221
04222
04223
04224
if (fNewRtoLReading != ped->
fRtoLReading) {
04225
04226 ped->
fRtoLReading = fNewRtoLReading;
04227
04228
if (ped->
fWrap) {
04229
04230
MLBuildchLines(ped, 0, 0,
FALSE,
NULL,
NULL);
04231
MLUpdateiCaretLine(ped);
04232 }
else {
04233
04234
MLScroll(ped,
FALSE, 0xffffffff, 0,
TRUE);
04235 }
04236
ECInvalidateClient(ped,
TRUE);
04237 }
04238 }