From 19b19ec305637be14f8e42e32b073268cbac81be Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 9 Jun 2026 13:52:46 +0900 Subject: [PATCH] [USER32][COMCTL32] Edit control: Fix alignment mask (#9115) Based on JIRA user I_Kill_Bug's "Edit Alignment.patch". JIRA issue: CORE-20631 - Add (ES_LEFT | ES_RIGHT | ES_CENTER) flags to style_change_mask variable. --- dll/win32/comctl32/edit.c | 5 + modules/rostests/win32/user32/CMakeLists.txt | 1 + .../win32/user32/editalign/CMakeLists.txt | 6 + .../win32/user32/editalign/editalign.c | 107 ++++++++++++++++++ .../win32/user32/editalign/editalign.ico | Bin 0 -> 23558 bytes .../win32/user32/editalign/editalign.rc | 29 +++++ .../win32/user32/editalign/resource.h | 2 + win32ss/user/user32/controls/edit.c | 5 + 8 files changed, 155 insertions(+) create mode 100644 modules/rostests/win32/user32/editalign/CMakeLists.txt create mode 100644 modules/rostests/win32/user32/editalign/editalign.c create mode 100644 modules/rostests/win32/user32/editalign/editalign.ico create mode 100644 modules/rostests/win32/user32/editalign/editalign.rc create mode 100644 modules/rostests/win32/user32/editalign/resource.h diff --git a/dll/win32/comctl32/edit.c b/dll/win32/comctl32/edit.c index ca52e7e496b..ed3829ed1ee 100644 --- a/dll/win32/comctl32/edit.c +++ b/dll/win32/comctl32/edit.c @@ -3991,8 +3991,13 @@ static LRESULT EDIT_WM_StyleChanged ( EDITSTATE *es, WPARAM which, const STYLES /* Only a subset of changes can be applied after the control * has been created. */ +#ifdef __REACTOS__ + style_change_mask = ES_UPPERCASE | ES_LOWERCASE | + ES_NUMBER | ES_LEFT | ES_RIGHT | ES_CENTER; +#else style_change_mask = ES_UPPERCASE | ES_LOWERCASE | ES_NUMBER; +#endif if (es->style & ES_MULTILINE) style_change_mask |= ES_WANTRETURN; diff --git a/modules/rostests/win32/user32/CMakeLists.txt b/modules/rostests/win32/user32/CMakeLists.txt index 757220d2aa3..be1aa50f51b 100644 --- a/modules/rostests/win32/user32/CMakeLists.txt +++ b/modules/rostests/win32/user32/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(biditext) +add_subdirectory(editalign) add_subdirectory(messagebox) add_subdirectory(paintdesktop) add_subdirectory(psmtest) diff --git a/modules/rostests/win32/user32/editalign/CMakeLists.txt b/modules/rostests/win32/user32/editalign/CMakeLists.txt new file mode 100644 index 00000000000..ed9f7188d2a --- /dev/null +++ b/modules/rostests/win32/user32/editalign/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_rc_deps(editalign.rc ${CMAKE_CURRENT_SOURCE_DIR}/editalign.ico) +add_executable(editalign editalign.c editalign.rc) +set_module_type(editalign win32gui UNICODE) +add_importlibs(editalign gdi32 user32 comctl32 msvcrt kernel32 ntdll) +add_rostests_file(TARGET editalign SUBDIR suppl) diff --git a/modules/rostests/win32/user32/editalign/editalign.c b/modules/rostests/win32/user32/editalign/editalign.c new file mode 100644 index 00000000000..78c216817a5 --- /dev/null +++ b/modules/rostests/win32/user32/editalign/editalign.c @@ -0,0 +1,107 @@ +/* + * PROJECT: ReactOS Tests + * LICENSE: LGPL-2.0+ (https://spdx.org/licenses/LGPL-2.0+) + * PURPOSE: Tests text alignment of EDIT control + * COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include "resource.h" + +static HINSTANCE g_hInstance = NULL; +static HWND g_hMainWnd = NULL; + +static void SetEditAlign(HWND hwndEdit, LONG_PTR add_style) +{ + LONG_PTR style = GetWindowLongPtr(hwndEdit, GWL_STYLE); + style &= ~(ES_LEFT | ES_CENTER | ES_RIGHT); + style |= add_style; + SetWindowLongPtr(hwndEdit, GWL_STYLE, style); + InvalidateRect(hwndEdit, NULL, TRUE); +} + +static void SetMultiline(HWND hwnd, HWND hwndEdit, BOOL bMultiline) +{ + TCHAR text[1024]; + GetWindowText(hwndEdit, text, ARRAYSIZE(text)); + + RECT rc; + GetWindowRect(hwndEdit, &rc); + MapWindowPoints(NULL, hwnd, (LPPOINT)&rc, sizeof(RECT) / sizeof(POINT)); + + DWORD exstyle = (LONG)GetWindowLongPtr(hwndEdit, GWL_EXSTYLE); + DWORD style = (LONG)GetWindowLongPtr(hwndEdit, GWL_STYLE); + style &= ~ES_MULTILINE; + if (bMultiline) + style |= ES_MULTILINE; + + DestroyWindow(hwndEdit); + CreateWindowEx(exstyle, TEXT("EDIT"), text, style, + rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hwnd, (HMENU)UlongToHandle(edt1), g_hInstance, NULL); + + HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); + SendDlgItemMessage(hwnd, edt1, WM_SETFONT, (WPARAM)hFont, TRUE); +} + +static INT_PTR CALLBACK +DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + g_hMainWnd = hwnd; + SetDlgItemText(hwnd, edt1, TEXT("Text")); + CheckRadioButton(hwnd, rad1, rad3, rad1); + return TRUE; + } + case WM_COMMAND: + { + HWND hwndEdit = GetDlgItem(hwnd, edt1); + switch (LOWORD(wParam)) + { + case IDCANCEL: // Cancel + EndDialog(hwnd, LOWORD(wParam)); + break; + case rad1: // Left + if (HIWORD(wParam) == BN_CLICKED) + SetEditAlign(hwndEdit, ES_LEFT); + break; + case rad2: // Center + if (HIWORD(wParam) == BN_CLICKED) + SetEditAlign(hwndEdit, ES_CENTER); + break; + case rad3: // Right + if (HIWORD(wParam) == BN_CLICKED) + SetEditAlign(hwndEdit, ES_RIGHT); + break; + case chx1: // Multiline + if (HIWORD(wParam) == BN_CLICKED) + { + if (IsDlgButtonChecked(hwnd, chx1) == BST_CHECKED) + SetMultiline(hwnd, hwndEdit, TRUE); + else + SetMultiline(hwnd, hwndEdit, FALSE); + } + } + break; + } + } + return 0; +} + +INT WINAPI +wWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPWSTR lpCmdLine, + INT nCmdShow) +{ + g_hInstance = hInstance; + InitCommonControls(); + DialogBoxW(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DialogProc); + return 0; +} diff --git a/modules/rostests/win32/user32/editalign/editalign.ico b/modules/rostests/win32/user32/editalign/editalign.ico new file mode 100644 index 0000000000000000000000000000000000000000..1073447c20ca46dca11c7f8ed0297cdf1188a5e0 GIT binary patch literal 23558 zcmeI430zh6w#OH<$l#2i5J$jy0#7+rND59VPMNbPrinR#peTxvvuSFE^OR^gr4{2j z0_Xbbe!9&LHwUJ&)a(VA@^1H5@5Z{nwa?i{L{KnAe2>5W&ic>)wf}pc&EEU`znjQ{ z>X1fLpNOpKM@yoWh}ExeOt-Nhnr%ho>x)d(JLF8X#hOsxl&(YM-$?2k)6;E;erT@N z*U+JsM8Pf8`beYRKl`fnH8dT4?HNVX2F<0*0LTJ<+%3eTFg`w>PM$nT%zU@1RW9?o zJ!rhOw*`&2PhhFgr#4-7K5m;o?>pzOff|$pM&qp}8#MCOTKV23tyH|DzuSiM^3vRE zhvRs8um{Y&1~iq+xDwTw>AxEiEPnHku4(E~cpP4lGjHXglIx5f^X{Sy!n zpzbGie`wVG0GE~UXJ%R2$~^f(lOQ=iRTMV$_ol?5t?9@(3&@g=Li>jyJs#=tmULiv zD>@4MHtd1ntzlc!!4W=mY=Q-BOL}`mE5t47&`58{hmO4HMMt5e5KDS@R0}#bT0`$a z$H#cm2V*@*7fPguJ{bE1;ueToQ1Uo;(oI1=lp1P-IPw))QSx{XN}bRQYEHU|Zj?FI z0_VeQk0!&ECNyTu7&`e(pmF2I(O+M#4>h2V zr`MxT!kp;iuzK`qm@^%i+Lk6vm_VQ5B>nj-PW0u>y7bu`D+&n-p;NQ%>1+h%aMC0? zJEsnvj*o5F_Dhf&Sx!UB6bAMH%p3+hr1^hLA_AGJ5cUAKbjJeN(CER z(@z`Q(E0TNRIsT76}&0xNT016N`1YhbKewhk4`%)29xJBegg zPaHr$Lq!Kh(ocsc(yy6|={Lix^iAI1sN~<*s0auC4d@@xuh4JM@6i83|Azj6N+6s@ zD*8J7zsol~?qT_D*BAFl#2aiX8OTB^Y7H;fspD8jLS@=HXbp9f($dn>p|s?bl=QoW z)U>4fT0=dlF2Q8()*{_WYiM-W3S|l#Y7LEb>FGNBt4v61qBS(t=_*%QI&{?4NvIx`gBnxg08vN(58}gr8|8Kt)cA+{fSC+tyIys(;C`moXDtj{Z3kg zZ$?I?>u30B4P7!aGArAEMwi<9cbhAjpC>abJ^vY*PihTav$85X|CyOxwT7NqSy}1n z_rKOd~&e96j%D#b5_;ZGiojbJBczd+;^zig>_ww}AwDk7&GzN{Qw|7e~kD=?j zY2se>3|Ja5cg|CW?!AY+FlOwiakD0bEm#t>Wbyo$X3Usq3}Z%5o)Y@X)cx-*TX5|C zNh=f9tcYG{2#P&&{LsO}M-T3O=iMFKcO7{9t;EEA#;|++)-4-0t$pqF&2PN9ZRehi zt5!dcKkogfFN&NtTnQszd=ZzmAtAF(AtYq{NMi{;N6wr#?Qy>rxDWr8n@U^`R%GMl ziqOJzSy*e06H(DTSQ+oR$*$u0EIZG)Kewv*J{7kF^j2>?>*_nmAz`otlL>bQU^28*%8=99SqcWPTxmL7m znm;8^?@6g)-RSf@CrY2$m6B!z;9k#$GG;$ThBQIvvxBzK(ULvx|HvH@*?&#W#jr=<-r0`f-^9 z<-O_xHKn|zP3c0M53C#IEpw&(Wz8sWc{9p~qN1W;n^XP@cgkPs3ALalb63$fE89`- zns$^A6|HYU=hi+=MH_wS>({#}&t!_;XiYzFYDG5^+ClB9(~Ljp=gl4IgzF~A>*9^+u9Y(o( zrc?gDY4mO4RJyc3l)i_G4!%g&4o{&QM?>k*fj#v7@o+l-Winknl>((gX>|GQ5z0T4 zLfL21Df_IRa-i(L>mbBM=dy5r`Vr-Q`xX5Q_no!(q^5Ie6%B3!9(KT^kBWm{-?1^C z>DM|^QjC#XpJ}=c zEhF_o#v3SPm%TR9>E1;7bGp>jl;rY4s%~woNPTZzT5?iKc{NgW>rfu3OHV1khZNoG ztt0jQbm>V+N#*sQqFayh{yJT`rOC-Dx{W9wc$e}`D1ZJgt_G_Sn8VCm>0u+lKNND%idxly67*NVG3Cx-puPmXeP09ql6ZqcHxh zO-RzEDzlN2gnzo7D4&G#azmOM$T5V&?;bvKasY@6FXl>RUM3S=m_I;L_9D%F5Qt8qXsv>$p%|dkY6guV*6l9elg`b??^w zsb_oj^6%dL$u8Y{_UIJ9xAW#V0v5c|V_KxX&#c|6SFTyUwbm6@DQFEe~ zM8vIH924I6Equ2I&7SenD;!(pX^JQmRF|i-5o)ko{g$B{E&maeSxp|4i?Q*3N3orn*mB}XB!l(CyG zXYQh_h8=Y6FWac-qg_;(lSP+vK8L=bYq_7&mAq5XX}Sts$%hqPxrI>z&euIAh z<$v(p^$$FQEm5Aw{sCM2Ocn=JZTLSo14GJ&PMRmo!M&ZkhpnZh1)ds6AZsgk-=M%g zy-mM}2L;x1?-D#{(DSA+XmCAuzu^AnFmOP9ckONI2JTOmPWNl*{#0=Pf#wE%8@YGA zRX%WF-zM(ef`bPm7(ap=yLW!>nE-$PUjF{i_UQR^cQU9qeuF>bSZzb?WHe zp?%wyt-M2*$dIJA5?FwQJ(AR{2;P!6K}QP^_9(ZB5%gtlz*H zRykf=v7UqRn>pimaug@tZp1H+4l)UfsfP`HD~CE7qEr{m0sq+k7q0FLfKr zD|-}qST|$#A8Tc*eJ=m(He-#C*?+9_VXUn%Z-W|F?Vla%LARG<0qc^?{$p*D;=lM? zQ++Nw2UtsG_8;r1823=-ZIHU^wn%>2va)?ucUpYIIxw^USpTK?sQN1YsBy8??ccq| z6aTS(&FnwcrPXME%WjX%Dc0GU{l}U*#+oQ)8^o5aU(?d!Kh^-6{l{8B#(FMg8^qQ$ zf6MwK{$tIe*?+8CRQwm;9|!-%N363n`;YaOX8*CKuEx*5_%A-I*FUxXSMNTno&V~c z@3QBg+WD_p^N)4vEay$xFQT&ht0twzKk-$3R?nYUUymGPsOjf_@lPZ^tNw!rFnMn@ z>U>K|jn@QQ+DY&WwfoY)u>~> z^tP0C61)yOIy$}!|6737DP8o){TF9czstr|N5$tRO`05s|6bsX)NI8{+tNYp>p@tx z-}~)LZ7)7IZQ4}vA8eGGt=RkRyE@vbj*8E!|KPdQ>>BI;Z4M#qtd+i0nc9_3OW#UbZFj3K*iHCo$>1s(te~7fkHCL7Fq8~_lEG6lSW5IMh4%=;2q`f*CF`t3a*pEY%&;326M^TQP4aKSfuA69&Lv-?0j1W1IgeW84RRi z!9X(jNCs<(dPafAM7#1OeS_mfUn10jz+xh9&0rQ893q3ARK@|D$Y2uDmozBpqY?)n$>1Ov%p-%JgtQEPlEFwa z7)b^@$wj;TO_F%|0&mISH5oi6gUdv`Bh-n(b27M22G7Z0HW?fzgW*IyKL)GGU^E$g zCxZiJaG(tSRs6>aYqHCaCO@#T3_g{?l`_~<2D8fGV9OWw3z%3%;9mI-Mb}|4trg4E z2K+4gKwlM&Q#xOcg=kv_53Bf=G>P!01X-P48)|2ub_O2j88BY#+{u~5%SNeu%HzC& zkHU9l9hS`Oo%33DzGa=31`2>Ilo%qlp`saZLIK|Lb6>jO^-0bcPreB<_C#nIv<6yT z1-*{CiBMJ780|(IkWb{Yxt}IsjlbJZD|))zSk|NQjb+_SNzy&r&|e(7f|4|?0BKXrUCcjocIB`V{~hm8L)##Q@N z#|P`j%^i%}4<54G#|LA`?#A)kfyJ!$@xeB-yCWsz`{(_r#;<2f%5y^Sr{!+HdMv8@ z?m<}@3`{52H;oVG)jYn8p??1##`jP?|9~gu`gX?c2Wx8{U&byyt{krqYP+RxHGpL` zj}OjQ$(HkvI_F{^)VS)LmL4A*t$BPf#;RNQHNNU|S$}2j7}C3&Ve-YH;?o9jv*g!d0H z-Zj8@ZvgKOAjbO!81EfmyqkdW-T}sY2N>@NU>6q`8Q%x*0bsEI49=gy|1&s$2Jf#} z@c(=^!ji%FD+23p%ttxi513>Kcjq%+QpJ%Z33|^kW*)y1X22T%lV{rBi&R!9idcwiydL@OL7<1Ey-K#T#|?Kyx4jrd2x+Oa^o5m=Ps#VoU_QG zIA^hAaZZeVarQ#n;tP?aC}*Kv@r5WVz6gD{h>EYp(m$>&w)p*vS+r5chHAqjo&oi= z6JLFPSg2!)mFE<HxnE%NA+#3wErf3>wUG4 z?r&`Woo-8&+k;2um;tSn@vodnFt-=qDzhD6nmKk*OQrn}8Jo=Q@6}fN7fJj0U}O8j zlScoMt<0;;t*VOhB!Ai97RLE|KlUcLYX*Xg~b?LZ_2g*0;NP zbvp3{5;O@=fBKy S2uFK+=#hr_`y5^6R{sMo*qd?y literal 0 HcmV?d00001 diff --git a/modules/rostests/win32/user32/editalign/editalign.rc b/modules/rostests/win32/user32/editalign/editalign.rc new file mode 100644 index 00000000000..9b08113af92 --- /dev/null +++ b/modules/rostests/win32/user32/editalign/editalign.rc @@ -0,0 +1,29 @@ +/* + * PROJECT: ReactOS Tests + * LICENSE: LGPL-2.0+ (https://spdx.org/licenses/LGPL-2.0+) + * PURPOSE: Tests text alignment of EDIT control + * COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS EditAlign test program" +#define REACTOS_STR_INTERNAL_NAME "editalign" +#define REACTOS_STR_ORIGINAL_FILENAME "editalign.exe" +#include +#include + +IDI_MAIN ICON "editalign.ico" + +IDD_MAIN DIALOG 0, 0, 215, 135 +CAPTION "EditAlign" +STYLE DS_CENTER | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION +FONT 9, "MS Shell Dlg" +{ + EDITTEXT edt1, 37, 13, 122, 61, ES_WANTRETURN + AUTORADIOBUTTON "ES_LEFT", rad1, 11, 83, 60, 14, WS_TABSTOP + AUTORADIOBUTTON "ES_CENTER", rad2, 77, 83, 60, 14, WS_TABSTOP + AUTORADIOBUTTON "ES_RIGHT", rad3, 145, 83, 60, 14, WS_TABSTOP + AUTOCHECKBOX "Multiline", chx1, 141, 115, 60, 14 +} diff --git a/modules/rostests/win32/user32/editalign/resource.h b/modules/rostests/win32/user32/editalign/resource.h new file mode 100644 index 00000000000..729562acb26 --- /dev/null +++ b/modules/rostests/win32/user32/editalign/resource.h @@ -0,0 +1,2 @@ +#define IDD_MAIN 100 +#define IDI_MAIN 100 diff --git a/win32ss/user/user32/controls/edit.c b/win32ss/user/user32/controls/edit.c index ceff2843f15..28e53c8cc24 100644 --- a/win32ss/user/user32/controls/edit.c +++ b/win32ss/user/user32/controls/edit.c @@ -4158,8 +4158,13 @@ static LRESULT EDIT_WM_StyleChanged ( EDITSTATE *es, WPARAM which, const STYLES /* Only a subset of changes can be applied after the control * has been created. */ +#ifdef __REACTOS__ + style_change_mask = ES_UPPERCASE | ES_LOWERCASE | + ES_NUMBER | ES_LEFT | ES_RIGHT | ES_CENTER; +#else style_change_mask = ES_UPPERCASE | ES_LOWERCASE | ES_NUMBER; +#endif if (es->style & ES_MULTILINE) style_change_mask |= ES_WANTRETURN;