riched20: Implement EM_SETPASSWORDCHAR and EM_GETPASSWORDCHAR
Matt Finnicum
mattfinn at gmail.com
Thu Aug 3 22:21:23 CDT 2006
Hi,
This patch implements EM_SETPASSWORDCHAR and EM_GETPASSWORDCHAR. It
also adds two needed string creation functions to string.c.
--Matt
---
dlls/riched20/editor.c | 22 ++++++++++++++++----
dlls/riched20/editor.h | 2 ++
dlls/riched20/editstr.h | 1 +
dlls/riched20/paint.c | 20 +++++++++++++++---
dlls/riched20/run.c | 46 ++++++++++++++++++++++++++++++++++++------
dlls/riched20/string.c | 26 ++++++++++++++++++++++++
dlls/riched20/tests/editor.c | 25 +++++++++++++++++++++++
7 files changed, 126 insertions(+), 16 deletions(-)
-------------- next part --------------
From 59aa6600243455d5eb8df6eae5ec7431280ba204 Mon Sep 17 00:00:00 2001
From: Matthew Finnicum <MattFinn at gmail.com>
Date: Thu, 3 Aug 2006 20:41:01 -0400
Subject: [PATCH] riched20: Implement EM_SETPASSWORDCHAR and EM_GETPASSWORDCHAR
---
dlls/riched20/editor.c | 22 ++++++++++++++++----
dlls/riched20/editor.h | 2 ++
dlls/riched20/editstr.h | 1 +
dlls/riched20/paint.c | 20 +++++++++++++++---
dlls/riched20/run.c | 46 ++++++++++++++++++++++++++++++++++++------
dlls/riched20/string.c | 26 ++++++++++++++++++++++++
dlls/riched20/tests/editor.c | 25 +++++++++++++++++++++++
7 files changed, 126 insertions(+), 16 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 390ac3b..cee0ace 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -58,7 +58,7 @@
- EM_GETOLEINTERFACE
+ EM_GETOPTIONS
+ EM_GETPARAFORMAT
- - EM_GETPASSWORDCHAR 2.0
+ + EM_GETPASSWORDCHAR 2.0
- EM_GETPUNCTUATION 1.0asian
+ EM_GETRECT
- EM_GETREDONAME 2.0
@@ -105,7 +105,7 @@
+ EM_SETOPTIONS (partially implemented)
- EM_SETPALETTE 2.0
+ EM_SETPARAFORMAT
- - EM_SETPASSWORDCHAR 2.0
+ + EM_SETPASSWORDCHAR 2.0
- EM_SETPUNCTUATION 1.0asian
+ EM_SETREADONLY no beep on modification attempt
+ EM_SETRECT
@@ -1412,7 +1412,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND
UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
UNSUPPORTED_MSG(EM_GETLIMITTEXT)
/* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
- UNSUPPORTED_MSG(EM_GETPASSWORDCHAR)
UNSUPPORTED_MSG(EM_GETREDONAME)
UNSUPPORTED_MSG(EM_GETTEXTMODE)
UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
@@ -1426,7 +1425,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND
UNSUPPORTED_MSG(EM_SETFONTSIZE)
UNSUPPORTED_MSG(EM_SETLANGOPTIONS)
UNSUPPORTED_MSG(EM_SETPALETTE)
- UNSUPPORTED_MSG(EM_SETPASSWORDCHAR)
UNSUPPORTED_MSG(EM_SETSCROLLPOS)
UNSUPPORTED_MSG(EM_SETTABSTOPS)
UNSUPPORTED_MSG(EM_SETTARGETDEVICE)
@@ -1927,6 +1925,10 @@ LRESULT WINAPI RichEditANSIWndProc(HWND
LPDATAOBJECT dataObj = NULL;
CHARRANGE range;
HRESULT hr = S_OK;
+
+ if (editor->cPasswordMask)
+ return 0; /* Copying or Cutting masked text isn't allowed */
+
ME_GetSelection(editor, (int*)&range.cpMin, (int*)&range.cpMax);
if(editor->lpOleCallback)
hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, &range, RECO_COPY, &dataObj);
@@ -2463,6 +2465,10 @@ LRESULT WINAPI RichEditANSIWndProc(HWND
LPVOID *ppvObj = (LPVOID*) lParam;
return CreateIRichEditOle(editor, ppvObj);
}
+ case EM_GETPASSWORDCHAR:
+ {
+ return editor->cPasswordMask;
+ }
case EM_SETOLECALLBACK:
if(editor->lpOleCallback)
IUnknown_Release(editor->lpOleCallback);
@@ -2504,7 +2510,13 @@ LRESULT WINAPI RichEditANSIWndProc(HWND
}
}
return ret;
- }
+ }
+ case EM_SETPASSWORDCHAR:
+ {
+ editor->cPasswordMask = wParam;
+ ME_RewrapRepaint(editor);
+ return 0;
+ }
default:
do_default:
return DefWindowProcW(hWnd, msg, wParam, lParam);
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index a4d4980..93952fd 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -75,6 +75,8 @@ const char *ME_GetDITypeName(ME_DIType t
int ME_GetOptimalBuffer(int nLen);
ME_String *ME_MakeString(LPCWSTR szText);
ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars);
+ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars);
+ME_String *ME_MakeStringB(int nMaxChars);
ME_String *ME_StrDup(ME_String *s);
void ME_DestroyString(ME_String *s);
void ME_AppendString(ME_String *s1, ME_String *s2);
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 10e4be2..7d096e8 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -320,6 +320,7 @@ typedef struct tagME_TextEditor
int mode;
BOOL bHideSelection;
BOOL AutoURLDetect_bEnable;
+ WCHAR cPasswordMask;
} ME_TextEditor;
typedef struct tagME_Context
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index f3f5ac1..f26583c 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -222,7 +222,8 @@ void ME_DrawGraphics(ME_Context *c, int
}
}
-static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para) {
+static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para)
+{
ME_Run *run = &rundi->member.run;
ME_DisplayItem *start = ME_FindItemBack(rundi, diStartRow);
int runofs = run->nCharOfs+para->nCharOfs;
@@ -247,9 +248,20 @@ static void ME_DrawRun(ME_Context *c, in
if (run->nFlags & MERF_GRAPHICS)
ME_DrawGraphics(c, x, y, run, para, (runofs >= nSelFrom) && (runofs < nSelTo));
else
- ME_DrawTextWithStyle(c, x, y,
- run->strText->szData, ME_StrVLen(run->strText), run->style, NULL,
- nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.nYPos, start->member.row.nHeight);
+ {
+ if (c->editor->cPasswordMask)
+ {
+ ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText));
+ ME_DrawTextWithStyle(c, x, y,
+ szMasked->szData, ME_StrVLen(szMasked), run->style, NULL,
+ nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.nYPos, start->member.row.nHeight);
+ ME_DestroyString(szMasked);
+ }
+ else
+ ME_DrawTextWithStyle(c, x, y,
+ run->strText->szData, ME_StrVLen(run->strText), run->style, NULL,
+ nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.nYPos, start->member.row.nHeight);
+ }
}
COLORREF ME_GetBackColor(ME_TextEditor *editor)
diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c
index a2c121a..d74d68f 100644
--- a/dlls/riched20/run.c
+++ b/dlls/riched20/run.c
@@ -532,6 +532,9 @@ int ME_CharFromPoint(ME_TextEditor *edit
*/
int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
{
+ ME_String *strRunText;
+ /* This could point to either the run's real text, or it's masked form in a password control */
+
int fit = 0, fit1 = 0;
HGDIOBJ hOldFont;
HDC hDC;
@@ -553,21 +556,30 @@ int ME_CharFromPointCursor(ME_TextEditor
return 0;
return 1;
}
+
+ if (editor->cPasswordMask)
+ strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(run->strText));
+ else
+ strRunText = run->strText;
hDC = GetDC(editor->hWnd);
hOldFont = ME_SelectStyleFont(editor, hDC, run->style);
- GetTextExtentExPointW(hDC, run->strText->szData, run->strText->nLen,
+ GetTextExtentExPointW(hDC, strRunText->szData, strRunText->nLen,
cx, &fit, NULL, &sz);
- if (fit != run->strText->nLen)
+ if (fit != strRunText->nLen)
{
int chars = 1;
- GetTextExtentPoint32W(hDC, run->strText->szData, fit, &sz2);
- fit1 = ME_StrRelPos(run->strText, fit, &chars);
- GetTextExtentPoint32W(hDC, run->strText->szData, fit1, &sz3);
+ GetTextExtentPoint32W(hDC, strRunText->szData, fit, &sz2);
+ fit1 = ME_StrRelPos(strRunText, fit, &chars);
+ GetTextExtentPoint32W(hDC, strRunText->szData, fit1, &sz3);
if (cx >= (sz2.cx+sz3.cx)/2)
fit = fit1;
}
+
+ if (editor->cPasswordMask)
+ ME_DestroyString(strRunText);
+
ME_UnselectStyleFont(editor, hDC, run->style, hOldFont);
ReleaseDC(editor->hWnd, hDC);
return fit;
@@ -584,6 +596,8 @@ int ME_PointFromChar(ME_TextEditor *edit
SIZE size;
HDC hDC = GetDC(editor->hWnd);
HGDIOBJ hOldFont;
+ ME_String *strRunText;
+ /* This could point to either the run's real text, or it's masked form in a password control */
if (pRun->nFlags & MERF_GRAPHICS)
{
@@ -591,10 +605,18 @@ int ME_PointFromChar(ME_TextEditor *edit
ME_GetGraphicsSize(editor, pRun, &size);
return 1;
}
+
+ if (editor->cPasswordMask)
+ strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(pRun->strText));
+ else
+ strRunText = pRun->strText;
+
hOldFont = ME_SelectStyleFont(editor, hDC, pRun->style);
- GetTextExtentPoint32W(hDC, pRun->strText->szData, nOffset, &size);
+ GetTextExtentPoint32W(hDC, strRunText->szData, nOffset, &size);
ME_UnselectStyleFont(editor, hDC, pRun->style, hOldFont);
ReleaseDC(editor->hWnd, hDC);
+ if (editor->cPasswordMask)
+ ME_DestroyString(strRunText);
return size.cx;
}
@@ -631,7 +653,17 @@ SIZE ME_GetRunSizeCommon(ME_Context *c,
* this is wasteful for MERF_NONTEXT runs, but that shouldn't matter
* in practice
*/
- ME_GetTextExtent(c, run->strText->szData, nLen, run->style, &size);
+
+ if (c->editor->cPasswordMask)
+ {
+ ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,nLen);
+ ME_GetTextExtent(c, szMasked->szData, nLen,run->style, &size);
+ ME_DestroyString(szMasked);
+ }
+ else
+ {
+ ME_GetTextExtent(c, run->strText->szData, nLen, run->style, &size);
+ }
*pAscent = run->style->tm.tmAscent;
*pDescent = run->style->tm.tmDescent;
size.cy = *pAscent + *pDescent;
diff --git a/dlls/riched20/string.c b/dlls/riched20/string.c
index b529373..57a304a 100644
--- a/dlls/riched20/string.c
+++ b/dlls/riched20/string.c
@@ -50,6 +50,32 @@ ME_String *ME_MakeStringN(LPCWSTR szText
return s;
}
+ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars)
+{ /* Make a string by repeating a char nMaxChars times */
+ int i;
+ ME_String *s = ALLOC_OBJ(ME_String);
+
+ s->nLen = nMaxChars;
+ s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
+ s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
+
+ for (i = 0;i<nMaxChars;i++)
+ s->szData[i] = cRepeat;
+ s->szData[s->nLen] = 0;
+ return s;
+}
+
+ME_String *ME_MakeStringB(int nMaxChars)
+{ /* Create a buffer (uninitialized string) of size nMaxChars */
+ ME_String *s = ALLOC_OBJ(ME_String);
+
+ s->nLen = nMaxChars;
+ s->nBuffer = ME_GetOptimalBuffer(s->nLen+1);
+ s->szData = ALLOC_N_OBJ(WCHAR, s->nBuffer);
+ s->szData[s->nLen] = 0;
+ return s;
+}
+
ME_String *ME_StrDup(ME_String *s)
{
return ME_MakeStringN(s->szData, s->nLen);
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index dd4f2dd..3424626 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -873,6 +873,30 @@ static void test_EM_SETUNDOLIMIT()
DestroyWindow(hwndRichEdit);
}
+static void test_ES_PASSWORD()
+{
+ /* This isn't hugely testable, so we're just going to run it through it's paces. */
+
+ HWND hwndRichEdit = new_richedit(NULL);
+ WCHAR result;
+
+ /* First, check the default of a regular control */
+ result = SendMessage(hwndRichEdit, EM_GETPASSWORDCHAR, 0, 0);
+ ok (result == 0,
+ "EM_GETPASSWORDCHAR returned %c by default, instead of NULL\n",result);
+
+ /* Now, set it to something normal */
+ SendMessage(hwndRichEdit, EM_SETPASSWORDCHAR, 'x', 0);
+ result = SendMessage(hwndRichEdit, EM_GETPASSWORDCHAR, 0, 0);
+ ok (result == 120,
+ "EM_GETPASSWORDCHAR returned %c (%d) when set to 'x', instead of x (120)\n",result,result);
+
+ /* Now, set it to something odd */
+ SendMessage(hwndRichEdit, EM_SETPASSWORDCHAR, (WCHAR)1234, 0);
+ result = SendMessage(hwndRichEdit, EM_GETPASSWORDCHAR, 0, 0);
+ ok (result == 1234,
+ "EM_GETPASSWORDCHAR returned %c (%d) when set to 'x', instead of x (120)\n",result,result);
+}
START_TEST( editor )
{
@@ -893,6 +917,7 @@ START_TEST( editor )
test_WM_GETTEXT();
test_EM_AUTOURLDETECT();
test_EM_SETUNDOLIMIT();
+ test_ES_PASSWORD();
/* Set the environment variable WINETEST_RICHED20 to keep windows
* responsive and open for 30 seconds. This is useful for debugging.
--
1.4.1.1
More information about the wine-patches
mailing list