VisualFreebasic重绘RichEdit实现文本框垂直居中

鄙人有强迫症,无论是用MFC还是.Net都特别不理解为什么自带的TextBox组件是垂直靠顶部对齐的,一定会想对应的解决方案让文字垂直居中。

现在在使用VisualFreebasic,其实使用的就是win32的API,所以TextBox也会存在同样的问题。

一般我都不会花心思去调整TextBox,一般都会使用支持设置边距的RichEdit来重绘一下非客户区。原则上我又不会去改作者的源码,一般会把组件复制一份,例如这里我会把组件的RichEdit复制一份,改成RichEditEx来实现。

奇怪的事情发生了,创建一个新项目,拽一个RichEditEx到窗体,预览是好的,但是运行之后控件进去之后窗体是空的。当我再拖一个RichEdit进去,编译,更奇怪的事情发生了,两个组件都赫然的显示在窗体上。

回想了一下,我记得MFC加载RichEdit都需要调用AfxInitRichEdit(),但是我全盘搜索并没有发现段代码。VisualFreebasic其实只是一个fbc的代码生成器,我们把编辑器的删除中间代码的选项取消:

然后创建两个项目TestA和TestB,前者拉原版的组件,后者拉扩展的组件。

对比CODEGEN_TestA_MAIN.bas发现会多一行代码

LoadLibraryW("MSFTEDIT.DLL")

也就是说,如果系统检测生成的代码中调用了原版的RichEdit就会自动的在生成的代码中加入加载RichEdit的dll,反之就不加载。通过进一步的测试,只要类文件的名字包含了\ClsRichEdit.inc就会加入LoadLibraryW("MSFTEDIT.DLL")代码。

剩下的问题就很简单了,创建一个空窗体,把原版的RichEdit拽一份上去,扩展的RichEditEx才能正常的使用。

下一步要实现实现垂直居中:

一、把RichEdit设置为单行模式

二、程序默认字体是微软雅黑,通过yGDI设置Font为10的高度,然后用(RichEditEx的高度-字体高度) / 2作为Top,编辑器自然就垂直居中。

三、Left一般设置为字体大小的五分之一

Sub Class_RichEditEx.Vertical()
   Dim rc As Rect
   Dim gg As yGDI = This.hWnd
   gg.Font, 10
   Dim h As Integer  = gg.GetTextHeight("汉")  
   SendMessage(This.hWnd, EM_GETRECT, 0, Varptr(rc))
   rc.top = (rc.bottom - rc.top - h) / 2 + 3 * gg.Dpi
   rc.bottom = rc.top + h
   rc.Left = h / 5
   SendMessage(This.hWnd, EM_SETRECT, 0, Varptr(rc))
End Sub

运行之后就是这个效果,会根据组件的高度和字体大小自动的调整

默认边框很难看,通过重绘NCPaint(非客户区),下面讲一下重绘边框调整颜色和宽度

网上非客户区的重绘教程比较少,慢慢摸索实现了

Function Class_RichEditEx.MsgProcedure(vhWnd As .hWnd ,wMsg As UInteger ,nwParam As wParam ,nlParam As lParam) As LResult
   Dim fp As FormControlsPro_TYPE Ptr
   Select Case wMsg
      Case WM_NCPAINT
         Dim As Rect rc, yrc
         GetWindowRect(hWndControl, @rc) 
         Dim gg As yGDI = yGDI(hWndControl, BGR(255, 255, 255), 0, 0, 0, 0, 0, 1)  
         
         gg.Pen 1 ,BGR(230 ,230 ,230) 
         gg.DrawCircleFrame(0, 0, rc.Right - rc.Left, rc.bottom - rc.top, 8, 8)
         ExcludeClipRect gg.m_nDC, rc.Left, rc.top, rc.Right, rc.bottom
         Return True
   End Select
   Function = 0
End Function
'在CONTROL_CODExx后面增加   
CONTROL_CODExx &= "   This." & clName & ".Vertical()" & vbCrLf

'在Dim LeaveHoverI As Long前面加入

'事件处理 ------------------------------
'增加
   Dim CALL_CONTROL_CUSTOM As String = "    If IDC = " & IDC & " Then  ' " & clName & vbCrLf
   CALL_CONTROL_CUSTOM &= "       " & Form_clName & "." & clName
   CALL_CONTROL_CUSTOM &= ".hWnd=hWndControl"  & vbCrLf
   CALL_CONTROL_CUSTOM &= "       tLResult = " & Form_clName & "." & clName
   CALL_CONTROL_CUSTOM &= ".MsgProcedure(hWndControl,wMsg, wParam, lParam)" & vbCrLf
   CALL_CONTROL_CUSTOM &= "       If tLResult Then Return tLResult"         & vbCrLf
   CALL_CONTROL_CUSTOM &= "    End If" & vbCrLf
   Insert_code(ProWinCode ,"'[CALL_CONTROL_CUSTOM]" ,CALL_CONTROL_CUSTOM)

   Dim LeaveHoverI As Long

至此完成,效果如下

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值