可以用 ES_PASSWORD 样式在 Edit 控件上绘制一个矩形吗?

Posted

技术标签:

【中文标题】可以用 ES_PASSWORD 样式在 Edit 控件上绘制一个矩形吗?【英文标题】:it's possible draw a rectangle on Edit control with ES_PASSWORD style? 【发布时间】:2017-07-25 16:40:36 【问题描述】:

我正在尝试在控件周围绘制一个矩形圆端,我做了这样的事情:

LRESULT CALLBACK WindPorc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)

    case WM_CTLCOLOREDIT:
    
        // device handle
        HDC Chdc = (HDC)wparam;
        // handle to control
        HWND CHand = (HWND)lparam;

        // new object pen...
        HPEN penx = CreatePen(PS_SOLID, 5, RGB(0, 255, 255));


        // apply pen to device handle and back up the original handle
        HGDIOBJ objb = SelectObject(Chdc, penx);

        // auto...
        RECT rectx;
        GetClientRect(CHand, &rectx);  

        // Now draw the rect with round borders...
        RoundRect(Chdc, (rectx.left -2), (rectx.top - 2), (rectx.right + 2), (rectx.bottom + 2), 5, 5);     

        // reset device hand...
        SelectObject(Chdc, objb);

        // Set text color...
        SetTextColor(Chdc, RGB(0, 255, 255));


        // clean up...
        DeleteObject(penx);
        DeleteObject(objb);


        // I should return a brush for the bk, but this don't care now...
        //return;
    




void InitUI()

    // just the edit control, isn't need the RegisterClass etc...

        HWND Edit1 = CreateWindowEx
        (
        NULL,
        L"EDIT",
        NULL,
        WS_CHILD | WS_VISIBLE |
        ES_LEFT | ES_MULTILINE, // Just a demonstration, it should be ES_PASSWORD
        10, 120, 200, 22,
        winx, // parent window HWND...
        (HMENU)TEXTBOX_1, // id
        (HINSTANCE)GetWindowLong(winx, GWL_HINSTANCE),
        NULL
        );

好的,看起来像这样:

但如果我将CreateWindowEx(); 上的样式更改为ES_PASSWORD,边缘就会消失,留下如下内容:

他们为什么会消失?

【问题讨论】:

【参考方案1】:

我会说实现在多个方面都是错误的:

Chdc 是一个 DC,它只能在编辑控件的客户区绘制,而您想在父窗口(对话框)的客户区绘制。 GetClientRect() 始终为左上角返回 (0,0),因为矩形相对于...编辑控件本身。 WM_CTLCOLOREDIT 可能不是绘制矩形的最佳位置,您需要进行一些测试以检查该消息何时真正被调用。

如果您希望保持这种实现方式,您应该:

使用父窗口的 DC 而不是编辑控件的 DC 进行绘制。 而不是 GetClientRect() 调用 GetWindowRect() 然后 ScreenToClient() 以相对于父窗口的客户区建立坐标。 使用WM_PAINT 消息(和BeginPaint()/EndPaint() 函数)获取父窗口的DC。

我会考虑不同的实现,创建一个 Owner-Drawn 静态控件,比编辑控件大几个像素,以某种方式放置在编辑控件“周围”(设置 WS_CLIPSIBLINGS 样式以确保编辑控件保持在静态控件之上)。绘图应执行处理WM_DRAWITEM 消息。我认为这个实现更健壮。

【讨论】:

以上是关于可以用 ES_PASSWORD 样式在 Edit 控件上绘制一个矩形吗?的主要内容,如果未能解决你的问题,请参考以下文章

修改Delphi 10.1.2 edit控件在android的复制剪切和粘贴样式

修改Delphi 10.1.2 edit控件在android的复制剪切和粘贴样式

html5中如何去掉input type date默认样式

特殊样式

Kindeditor 编辑区样式结构

Android 设置EditText的光标样式