Announcement

Collapse
No announcement yet.

Character Spacing (Not Kerning)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Is there any popcorn left?

    Comment


    • #22
      Just finished! Down to salt and unpopped kernels at the bottom of the bowl. Trying to talk myself to focusing on the technical tasks at hand. The wife and grandkids are asleep, so I'm a free bird for the next 3-4 hours.

      Comment


      • #23
        Good, so stay tuned, popcorn on your laps...

        Comment


        • #24
          Click image for larger version  Name:	SpacedCharacters.png Views:	1 Size:	37.5 KB ID:	776932

          Code:
          #COMPILE EXE '#Win 9.07#
          #DIM ALL
          #INCLUDE "Win32Api.inc"
          #INCLUDE "RichEdit.inc"
          '#RESOURCE "YourResource.pbr"
          
          %RichEdit01             = 101
          %ButtonHorizontalExpand = 201
          %ButtonHorizontalNormal = 202
          %ButtonVerticalExpand   = 203
          %ButtonVerticalNormal   = 204
          
          GLOBAL hDlg        AS DWORD
          GLOBAL hRichEdit01 AS DWORD
          '_____________________________________________________________________________
          
          FUNCTION reRichEditFromStringCallBack(BYVAL pDwordArray AS DWORD POINTER, BYVAL pRichEditBuffer AS DWORD, _
                                                BYVAL cb AS LONG, BYREF pcb AS LONG) AS LONG
           'pDwordArray     = Address of a two dword array used by application to send a string pointer and a string lenght
           'pRichEditBuffer = Address of the rich edit buffer who will receive the string data
           'cb              = Maximum byte count that the richEdit control could accept
           'pcb             = Bytes count of the buffer that was pushed successfully at pRichEditBuffer by the application
          
           pcb = MIN(@pDwordArray[1], cb)
           IF pcb > 0 THEN
             CopyMemory(pRichEditBuffer, @pDwordArray[0], pcb)
             @pDwordArray[0] = @pDwordArray[0] + pcb
             @pDwordArray[1] = @pDwordArray[1] - pcb
           END IF
          
          END FUNCTION
          '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __
          
          FUNCTION reRichEditFromStringReplace(BYVAL hRichEdit AS DWORD, BYVAL sRtfText AS STRING) AS LONG
           'Send rtf String to a RichEdit
           LOCAL EditStreamInfo AS EDITSTREAM
           DIM dwArray(0 TO 1)  AS DWORD
          
           dwArray(0)                 = STRPTR(sRtfText)
           dwArray(1)                 = LEN(sRtfText)
           EditStreamInfo.dwCookie    = VARPTR(dwArray(0))
           EditStreamInfo.pfnCallback = CODEPTR(reRichEditFromStringCallBack)
           FUNCTION = SendMessage(hRichEdit, %EM_STREAMIN, %SF_RTF OR %SFF_PLAINRTF OR %SFF_SELECTION, VARPTR(EditStreamInfo))
           IF EditStreamInfo.dwError THEN WinBeep(1500, 100) : WinBeep(1500, 100)
          
          END FUNCTION
          '_____________________________________________________________________________
          
          FUNCTION reRichEditToStringCallBack(BYVAL pString AS STRING POINTER, BYVAL pRichEditBuffer AS DWORD, _
                                              BYVAL cb AS LONG, BYREF pcb AS LONG) AS LONG
           'pString         Application dynamic string pointer
           'pRichEditBuffer Address of the rich edit buffer who will give the string data
           'cb              Number of bytes written at pRichEditBuffer
           'pcb             Bytes count of the buffer that was pushed successfully at pRichEditBuffer by the application
          
           LOCAL StringPreviousLen AS DWORD
          
           StringPreviousLen = LEN(@pString)
           @pString          = @pString & NUL$(cb)
           pcb               = cb 'Needed to avoid a EditStreamInfo.dwError
           CopyMemory(STRPTR(@pString) + StringPreviousLen, pRichEditBuffer, cb)
          
          END FUNCTION
          '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __
          
          FUNCTION reRichEditToString(BYVAL hRichEdit AS DWORD) AS STRING
           'Get selected text string from a RichEdit
           LOCAL EditStreamInfo AS EDITSTREAM
           LOCAL sBuffer        AS STRING
          
           EditStreamInfo.dwCookie    = VARPTR(sBuffer)
           EditStreamInfo.pfnCallback = CODEPTR(reRichEditToStringCallBack)
           SendMessage(hRichEdit, %EM_STREAMOUT, %SF_TEXT OR %SFF_SELECTION, VARPTR(EditStreamInfo))
           FUNCTION = sBuffer
           IF EditStreamInfo.dwError THEN WinBeep(2500, 100) : WinBeep(2500, 100)
          
          END FUNCTION
          '______________________________________________________________________________
          
          CALLBACK FUNCTION DlgProc() AS LONG
           LOCAL ParaFormt2   AS PARAFORMAT2
           LOCAL sRtfText     AS STRING
          
           SELECT CASE CBMSG
          
             CASE %WM_COMMAND
               SELECT CASE CBCTL
          
                 CASE %ButtonHorizontalExpand                           '-Expand selected characters horizontally, use negative number to compress.
                   IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN       '-Note: For backward compatibility use both expndtw and expnd, ratio is 5 to 1.
                     sRtfText = reRichEditToString(hRichEdit01)         'Get selected text.
                     REPLACE $CRLF WITH "\par " IN sRtfText             'Replace CrLf with "\par".
                     sRtfText = "{\rtf1\expndtw360\expnd72 " & sRtfText & "\expnd0\expndtw0}" 'Insert expand instruction.
                     reRichEditFromStringReplace(hRichEdit01, sRtfText) 'Send rtf String to a RichEdit control.
                   END IF
          
                 CASE %ButtonHorizontalNormal                           '-UnExpand selected characters horizontally.
                   IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN       '-Note: For backward compatibility use both expndtw and expnd.
                     sRtfText = reRichEditToString(hRichEdit01)         'Get selected text.
                     REPLACE $CRLF WITH "\par " IN sRtfText             'Replace CrLf with "\par".
                     sRtfText = "{\rtf1 \expndtw0\expnd0 " & sRtfText & "\expnd0\expndtw0}"  'Insert unExpand instruction with zero value.
                     reRichEditFromStringReplace(hRichEdit01, sRtfText) 'Send rtf String to a RichEdit control.
                   END IF
          
                 CASE %ButtonVerticalExpand
                   IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     ParaFormt2.dwMask           = %PFM_LINESPACING     'This is used for line spacing
                     ParaFormt2.dyLineSpacing    = 30                   '20 = one line height, 40 = 2, 10 = ½
                     ParaFormt2.bLineSpacingRule = 5                    'Five mean that dyLineSpacing is in twentieth, see MSDN
                     ParaFormt2.cbSize           = SIZEOF(PARAFORMAT2)  'Set PARAFORMAT2 version
                     SendMessage(hRichEdit01, %EM_SETPARAFORMAT, 0, VARPTR(ParaFormt2)) 'Set line spacing
                   END IF
          
                 CASE %ButtonVerticalNormal
                   IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     ParaFormt2.dwMask           = %PFM_LINESPACING     'This is used for line spacing
                     ParaFormt2.dyLineSpacing    = 20                   '20 = one line height, 40 = 2, 10 = ½
                     ParaFormt2.bLineSpacingRule = 5                    'Five mean that dyLineSpacing is in twentieth, see MSDN
                     ParaFormt2.cbSize           = SIZEOF(PARAFORMAT2)  'Set PARAFORMAT2 version
                     SendMessage(hRichEdit01, %EM_SETPARAFORMAT, 0, VARPTR(ParaFormt2)) 'Set line spacing
                   END IF
          
             END SELECT
          
             CASE %WM_SIZE
               IF CBWPARAM <> %SIZE_MINIMIZED THEN 'Size RichEdit control
                 MoveWindow(hRichEdit01, 5, 35, LO(WORD, CBLPARAM) - 10 , HI(WORD, CBLPARAM) - 40, %TRUE)
               END IF
          
           END SELECT
          
          END FUNCTION
          '_____________________________________________________________________________
          
          FUNCTION PBMAIN () AS LONG
           LOCAL sText AS STRING
           LOCAL hIcon AS DWORD
           LOCAL hLib  AS DWORD
           LOCAL hFont AS DWORD
          
           sText = "This code show how to increment the horizontal lenght " & $CRLF & _
                   "of every characters in a RichEdit50W control "          & $CRLF & _
                   "via EM_STREAMIN  / expndtw."                            & $CRLF & _
                   ""                                                       & $CRLF & _
                   "Vertical spacing can also be done "                     & $CRLF & _
                   "via PARAFORMAT / PFM_LINESPACING."                      & $CRLF
          
           hFont = CreateFont(36, 0, _       'Height, Width usually 0,
                              00, 0, _       'Escapement(angle), Orientation
                              00, 0, 0, 0, _ 'Bold, Italic, Underline, Strikethru
                              00, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
                              %DEFAULT_QUALITY, %FF_DONTCARE,  "Tahoma")
          
           hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) 'Get icon 294 from Shell32.dll
          
           DIALOG FONT "Segoe UI", 9
           DIALOG NEW %HWND_DESKTOP, "RichEdit characters expansion", , , 453, 180, _
           %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX  OR %WS_THICKFRAME OR %WS_SYSMENU, 0 TO hDlg
          
           CONTROL ADD BUTTON, hDlg, %ButtonHorizontalExpand, "Expand selected text horizontally",     3, 4, 110, 13
          
           CONTROL ADD BUTTON, hDlg, %ButtonHorizontalNormal, "UnExpand selected text horizontally", 115, 4, 110, 13
          
           CONTROL ADD BUTTON, hDlg, %ButtonVerticalExpand,   "Expand selected text vertically",     227, 4, 110, 13
          
           CONTROL ADD BUTTON, hDlg, %ButtonVerticalNormal,   "UnExpand selected text vertically",   340, 4, 110, 13
          
           hLib = LoadLibrary("MsftEdit.dll") 'Use latest RichEdit version 4.1
           CONTROL ADD "RichEdit50W", hDlg, %RichEdit01, sText, 4, 15, 450, 150, _
           %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %WS_HSCROLL OR %WS_VSCROLL OR %ES_MULTILINE OR _
           %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL OR %ES_NOHIDESEL OR %ES_SAVESEL OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE
          
           hRichEdit01 = GetDlgItem(hDlg, %RichEdit01) 'Get RichEdit control handle
           SendMessage(hRichEdit01, %EM_SETTYPOGRAPHYOPTIONS, %TO_ADVANCEDTYPOGRAPHY OR %TO_SIMPLELINEBREAK, %TO_ADVANCEDTYPOGRAPHY OR %TO_SIMPLELINEBREAK) 'Needed for horizontal spacing
           SendMessage(hRichEdit01, %WM_SETFONT, hFont, 0)     'Set font
           SendMessage(hRichEdit01, %EM_SETTARGETDEVICE, 0, 0) 'Enable wordwrap
          
           SetClassLong(hDlg, %GCL_HICONSM, hIcon) 'Set dialog small icon
           SetClassLong(hDlg, %GCL_HICON,   hIcon) 'Set dialog icon
          
           DIALOG SHOW MODAL hDlg CALL DlgProc
          
           FreeLibrary(hLib)   'Clean up
           DestroyIcon(hIcon)  'Clean up
           DeleteObject(hFont) 'Clean up
          
          END FUNCTION
          '_____________________________________________________________________________
          '
          Last edited by Pierre Bellisle; 8 Dec 2018, 11:24 PM.

          Comment


          • #25
            Pierre!
            It's Christmas time in Texas! Thank you very much for the example and the time spent on it. Testing it now ...

            I am able to increase character spacing. To kick it off, I have to select something. Pressing the button will expand the selection. Then, anything I continue typing will be expanded, unless it is in an array outside the original selection.

            I modified the style and confirmed that it will wrap correctly with the extra spacing.

            You seem to have hit the nail on the head - most excellent! I'll continue to play with it and give you more feedback. I'm sure I'll have questions about what

            Comment


            • #26
              I don't have that PBR, so I commented it out. What is in it?

              Comment


              • #27
                Only aesthetic. A manifest for CommonControl6 theme...

                [I also did enable word wrap in above code.]

                Comment


                • #28
                  Hi Pierre!

                  Analyzing the code ...

                  For horizontal spacing ...
                  • You had to give the RichEdit several styles to enable this all to work.
                  • The RichEdit control was subclassed are part of getting/setting the RTF code
                  • You extract the RTF text
                  • Wrap the RTF in {\rtf1\expndtw360 " and \expndtw0}
                  • Place the wrapped text back in the RichEdit
                  • At that point anything typed in between those RTF strings will be displayed with extra spaces.
                  • I assume I could insert the RTF string pairs in when I first load the RichEdit
                  Vertical spacing is handled control-wide by setting the PARAFORMAT2 structure. RTF string insertions are not required to manage vertical spacing.

                  Does that description describe it reasonably well?

                  I still need to analyze the code more but I wanted to make sure that my first impressions match reality!

                  Comment


                  • #29
                    Pierre,
                    Is the CopyMemory function similar to the PowerBASIC Memory Copy? I've not used either but they appear to be identical

                    I assume MSDN had some content that was helpful in putting this together? Can you point out any links that might be useful to me in using or even eventually tweaking the code?

                    Was there anything in your testing for me to be aware of?

                    Comment


                    • #30
                      Pierre,
                      I also gave URL detection a try, but that seems to crash the test. The URL string is highlighted in the control, but clicking on it causes the app to crash.

                      Actually, sometimes it crashes and sometimes it just doesn't respond. I'll test some more.

                      Here's my test code ...

                      Code:
                      #Compile Exe '#Win 9.07#
                      #Dim All
                      
                      #Debug Error On
                      #Debug Display On
                      
                      #Include "Win32Api.inc"
                      #Include "RichEdit.inc"
                      '#RESOURCE "AddResource.pbr"
                      
                      %RichEdit01                 = 101
                      %ButtonEditHorizontalExpand = 201
                      %ButtonEditHorizontalNormal = 202
                      %ButtonEditVerticalExpand   = 203
                      %ButtonEditVerticalNormal   = 204
                      
                      Global hDlg        As Dword
                      Global hRichEdit01 As Dword
                      '_____________________________________________________________________________
                      
                      Function reRichEditFromStringCallBack(ByVal pDwordArray As Dword Pointer, ByVal pRichEditBuffer As Dword, _
                                                            ByVal cb As Long, ByRef pcb As Long) As Long
                       'pDwordArray     = Address of a two dword array used by application to send a string pointer and a string lenght
                       'pRichEditBuffer = Address of the rich edit buffer who will receive the string data
                       'cb              = Maximum byte count that the richEdit control could accept
                       'pcb             = Bytes count of the buffer that was pushed successfully at pRichEditBuffer by the application
                      
                       pcb = Min(@pDwordArray[1], cb)
                       If pcb > 0 Then
                         CopyMemory(pRichEditBuffer, @pDwordArray[0], pcb)
                         @pDwordArray[0] = @pDwordArray[0] + pcb
                         @pDwordArray[1] = @pDwordArray[1] - pcb
                       End If
                      
                      End Function
                      '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __
                      
                      Function reRichEditFromStringReplace(ByVal hRichEdit As Dword, ByVal sRtfText As String) As Long 'Send rtf String to a RichEdit
                       Local EditStreamInfo As EDITSTREAM
                       Dim dwArray(0 To 1)  As Dword
                      
                       dwArray(0)                 = StrPtr(sRtfText)
                       dwArray(1)                 = Len(sRtfText)
                       EditStreamInfo.dwCookie    = VarPtr(dwArray(0))
                       EditStreamInfo.dwError     = 0
                       EditStreamInfo.pfnCallback = CodePtr(reRichEditFromStringCallBack) 'horizonta-spacing
                       Function = SendMessage(hRichEdit, %EM_STREAMIN, %SF_RTF Or %SFF_PLAINRTF Or %SFF_SELECTION, VarPtr(EditStreamInfo)) 'horizonta-spacing
                       If EditStreamInfo.dwError Then WinBeep(1500, 100)
                      
                      End Function
                      '_____________________________________________________________________________
                      
                      Function reRichEditToStringCallBack(ByVal pString As String Pointer, ByVal pRichEditBuffer As Dword, _
                                                          ByVal cb As Long, ByRef pcb As Long) As Long
                       'pString         Application dynamic string pointer
                       'pRichEditBuffer Address of the rich edit buffer who will give the string data
                       'cb              Number of bytes written at pRichEditBuffer
                       'pcb             Bytes count of the buffer that was pushed successfully at pRichEditBuffer by the application
                      
                       Local StringPreviousLen As Dword
                      
                       StringPreviousLen = Len(@pString)
                       @pString          = @pString & Nul$(cb)
                       CopyMemory(StrPtr(@pString) + StringPreviousLen, pRichEditBuffer, cb)
                      
                      End Function
                      '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __
                      
                      Function reRichEditToString(ByVal hRichEdit As Dword) As String 'Get selected text string from a RichEdit
                       Local EditStreamInfo As EDITSTREAM
                       Local sBuffer        As String
                      
                       EditStreamInfo.dwCookie    = VarPtr(sBuffer)
                       EditStreamInfo.pfnCallback = CodePtr(reRichEditToStringCallBack)
                       SendMessage(hRichEdit, %EM_STREAMOUT, %SF_TEXT Or %SFF_SELECTION, VarPtr(EditStreamInfo))
                       Function = sBuffer
                      
                      End Function
                      '______________________________________________________________________________
                      
                      CallBack Function DlgProc() As Long
                       Local ParaFormt2   As PARAFORMAT2
                       Local sRtfText     As String
                       Local ClientHeight As Long
                       Local ClientWidth  As Long
                      
                       Select Case CbMsg
                      
                         Case %WM_Command
                           Select Case CbCtl
                      
                             Case %ButtonEditHorizontalExpand
                               If CbCtlMsg = %BN_Clicked Or CbCtlMsg = 1 Then
                                 sRtfText = reRichEditToString(hRichEdit01)
                                 Replace $CrLf With "\par " In sRtfText
                                 sRtfText = "{\rtf1\expndtw360 " & sRtfText & "\expndtw0}" 'Use negative number to compress
                                 reRichEditFromStringReplace(hRichEdit01, sRtfText)        'Send rtf String to a RichEdit
                               End If
                      
                             Case %ButtonEditHorizontalNormal
                               If CbCtlMsg = %BN_Clicked Or CbCtlMsg = 1 Then
                                 sRtfText = reRichEditToString(hRichEdit01)
                                 Replace $CrLf With "\par " In sRtfText
                                 sRtfText = "{\rtf1 \expndtw0 " & sRtfText & "\expndtw0}" 'Use negative number to compress
                                 reRichEditFromStringReplace(hRichEdit01, sRtfText)       'Send rtf String to a RichEdit
                               End If
                      
                             Case %ButtonEditVerticalExpand
                               If CbCtlMsg = %BN_Clicked Or CbCtlMsg = 1 Then
                                 ParaFormt2.dwMask           = %PFM_LINESPACING
                                 ParaFormt2.dyLineSpacing    = 30 '20 = one line height, 40 = 2, 10 = ½
                                 ParaFormt2.bLineSpacingRule = 5  'Five mean that dyLineSpacing is in twentieth, see MSDN
                                 ParaFormt2.cbSize           = SizeOf(PARAFORMAT2)
                                 SendMessage(hRichEdit01, %EM_SETPARAFORMAT, 0, VarPtr(ParaFormt2))
                               End If
                      
                             Case %ButtonEditVerticalNormal
                               If CbCtlMsg = %BN_Clicked Or CbCtlMsg = 1 Then
                                 ParaFormt2.dwMask           = %PFM_LINESPACING
                                 ParaFormt2.dyLineSpacing    = 20 '20 = one line height, 40 = 2, 10 = ½
                                 ParaFormt2.bLineSpacingRule = 5  'Five mean that dyLineSpacing is in twentieth, see MSDN
                                 ParaFormt2.cbSize           = SizeOf(PARAFORMAT2)
                                 SendMessage(hRichEdit01, %EM_SETPARAFORMAT, 0, VarPtr(ParaFormt2))
                               End If
                      
                         End Select
                      
                         Case %WM_Notify
                            If Cb.NmId = %RichEdit01 And Cb.NmCode = %EN_Link Then RichEditHyperLink(hDlg, Cb.LParam)
                      
                         Case %WM_Size
                           If CbWParam <> %SIZE_MINIMIZED Then
                             ClientWidth  = Lo(Word, CbLParam)
                             ClientHeight = Hi(Word, CbLParam)
                             MoveWindow(hRichEdit01, 5, 35, ClientWidth - 10 , ClientHeight - 40, %TRUE)
                             InvalidateRect(hRichEdit01, ByVal %NULL, %TRUE) : UpdateWindow(hRichEdit01)
                           End If
                      
                       End Select
                      
                      End Function
                      '_____________________________________________________________________________
                      
                      Function PBMain () As Long
                       Local sText As String
                       Local hIcon As Dword
                       Local hLib  As Dword
                       Local hFont As Dword
                      
                       sText = "This code show how to increment the horizontal lenght " & $CrLf & _
                               "of every characters in a RichEdit50W control "          & $CrLf & _
                               "via EM_STREAMIN / EM_STREAMOUT / expndtw."              & $CrLf & _
                               ""                                                       & $CrLf & _
                               "http://www.garybeene.com"                               & $CrLf & _
                               ""                                                       & $CrLf & _
                               "Vertical spacing can also be done "                     & $CrLf & _
                               "via PARAFORMAT."                                        & $CrLf
                      
                       hFont = CreateFont(36, 0, _       'Height, Width usually 0,
                                          00, 0, _       'Escapement(angle), Orientation
                                          00, 0, 0, 0, _ 'Bold, Italic, Underline, Strikethru
                                          00, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
                                          %DEFAULT_QUALITY, %FF_DONTCARE,  "Tahoma")
                      
                       hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) 'o
                      
                       Dialog Font "Segoe UI", 9
                       Dialog New %HWND_Desktop, "RichEdit characters expansion", , , 453, 220, _
                       %WS_Caption Or %WS_MinimizeBox Or %WS_MaximizeBox  Or %WS_ThickFrame Or %WS_SysMenu, 0 To hDlg
                      
                       Control Add Button, hDlg, %ButtonEditHorizontalExpand, "Expand selected text horizontally",     3, 4, 110, 13
                      
                       Control Add Button, hDlg, %ButtonEditHorizontalNormal, "UnExpand selected text horizontally", 115, 4, 110, 13
                      
                       Control Add Button, hDlg, %ButtonEditVerticalExpand,   "Expand selected text vertically",     227, 4, 110, 13
                      
                       Control Add Button, hDlg, %ButtonEditVerticalNormal,   "UnExpand selected text vertically",   340, 4, 110, 13
                      
                       hLib = LoadLibrary("MsftEdit.dll")
                       Control Add "RichEdit50W", hDlg, %RichEdit01, sText, 4, 15, 450, 150, _
                                  %WS_Child Or %WS_ClipSiblings Or %WS_Visible Or %ES_MultiLine Or %WS_VScroll _
                                  Or %ES_AutoVScroll Or %ES_WantReturn Or %ES_NoHideSel Or %WS_TabStop, %WS_Ex_ClientEdge
                      
                      ' %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %WS_HSCROLL OR %WS_VSCROLL OR %ES_MULTILINE OR _
                      ' %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL OR %ES_NOHIDESEL OR %ES_SAVESEL OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE
                      
                       hRichEdit01 = GetDlgItem(hDlg, %RichEdit01)
                      
                      SendMessage hRichEdit01, %EM_SetEventMask, 0, %ENM_SelChange Or %ENM_Link
                      SendMessage hRichEdit01,  %EM_AUTOURLDETECT, %True, 0
                      
                       SendMessage(hRichEdit01, %EM_SETTYPOGRAPHYOPTIONS, %TO_ADVANCEDTYPOGRAPHY Or %TO_SIMPLELINEBREAK, %TO_ADVANCEDTYPOGRAPHY Or %TO_SIMPLELINEBREAK) 'Needed for horizonta-spacing
                       SendMessage(hRichEdit01, %WM_SETFONT, hFont, 0)
                      
                      
                       SetClassLong(hDlg, %GCL_HICONSM, hIcon)
                       SetClassLong(hDlg, %GCL_HICON,   hIcon)
                      
                       Dialog Show Modal hDlg Call DlgProc
                      
                       FreeLibrary(hLib)
                       DestroyIcon(hIcon)
                       DeleteObject(hFont)
                      
                      End Function
                      '_____________________________________________________________________________
                      '
                      
                      Function RichEditHyperLink(ByVal hWnd As Dword, ByVal lpLink As Dword) As Long
                         Local enlinkPtr As ENLINK Ptr, tr As TEXTRANGE, linkText As String
                         enlinkPtr    = lpLink
                         tr.chrg      = @enLinkPtr.chrg
                         linkText     = Space$(tr.chrg.cpMax - tr.chrg.cpMin + 2)
                         tr.lpstrText = StrPtr(linkText)
                         Control Send hWnd, %RICHEDIT01, %EM_GETTEXTRANGE, 0, VarPtr(tr)
                         Select Case @enLinkPtr.Msg
                            Case %WM_LButtonUp
                               ShellExecute(%NULL, "open", ByCopy linkText, "", "", %SW_Show)
                               Function = %True                    ' Signal that we processed this
                         End Select
                      End Function

                      Comment


                      • #31
                        Pierre,

                        Additional test ... I included %Unicode = 1 and that seems to work.

                        Comment


                        • #32
                          Hey,

                          TO_ADVANCEDTYPOGRAPHY is needed with RichEdit50W, this one was pretty hard to find, beside that, I did not need any particular style.

                          There is no subclassing in this code. reRichEditToStringCallBack and reRichEditFromStringCallBack are special way to communicate with rich edit.

                          Replacing CrLf with "\par " was necessary.

                          PowerBASIC MEMORY COPY is probably a front end for the CopyMemory() api.

                          I assume MSDN had some content that was helpful in putting this together? Can you point out any links that might be useful to me in using or even eventually tweaking the code?
                          Nope, I had to do it all the way, I did saw very few things that could be helpfull for this code. It was more from my first intuition and deductions, then trial and try again...

                          Unlike WIndows 10, text must be inserted after SendMessage / EM_AUTOURLDETECT for url detection under Windows Seven.

                          Here is the code I use for EN_LINK. It's working well on my side, expanded or not...

                          Code:
                             CASE %WM_NOTIFY
                                IF CBNMID = %RichEdit01 AND CBNMCODE = %EN_LINK THEN
                                  LOCAL pEnLink  AS ENLINK POINTER
                                  LOCAL TxtRange AS TEXTRANGE
                                  LOCAL ChrRange AS CHARRANGE
                                  LOCAL sUrl     AS STRING
                          
                                  pEnLink            = CBLPARAM
                                  TxtRange.chrg      = @pEnLink.chrg
                                  sUrl               = NUL$((TxtRange.chrg.cpMax - TxtRange.chrg.cpMin + 2) * 2)
                                  TxtRange.lpstrText = STRPTR(sUrl)
                                  SendMessage(hRichEdit01, %EM_GETTEXTRANGE, 0, VARPTR(TxtRange))
                                  IF @pEnLink.msg = %WM_LBUTTONDBLCLK THEN 'WM_LBUTTONDBLCLK - WM_LBUTTONUP - WM_LBUTTONDOWN 
                                    ShellExecute(%NULL, "open", ACODE$(sUrl), "", "", %SW_SHOW)
                                    FUNCTION = %TRUE
                                  END IF
                                END IF
                          Last edited by Pierre Bellisle; 9 Dec 2018, 09:10 PM.

                          Comment


                          • #33
                            Something that may work for you is the adjustments in CreateFont() where you can set the height and width as well as the weight of a font. Not exactly the effect you have mentioned but it may be useful to you.
                            hutch at movsd dot com
                            The MASM Forum

                            www.masm32.com

                            Comment


                            • #34
                              Pierre, thanks for the additional comments - helpful! I'll be out-of-pocket for a while and will give the code some further testing when I get back.

                              Steve, thanks for the info. I'll keep it in mind.

                              Comment


                              • #35
                                And if one day you have a need for kerning you may try 5
                                on a string like "AVAVAVAVAVAVAVAVAVAVAVAVAVAVAVAV".
                                Code:
                                sRtfText = "{\rtf1\kerning5 " & sRtfText & "\kerning0}"

                                Comment


                                • #36
                                  Howdy, Pierre!
                                  Thanks for that additional tip. I'm almost back in control of my time and will test out your character spacing some more tomorrow.

                                  Comment


                                  • #37
                                    Hi Pierre,
                                    TO_ADVANCEDTYPOGRAPHY is needed with RichEdit50W, this one was pretty hard to find..
                                    Thanks for finding %EM_SETTYPOGRAPHYOPTIONS ! It solved a problem I was struggling with.
                                    In Win10 Pro 64bit \expndtwN did work in my test code. However the same code would not work in Win7... - I was stumped, until I used the fix that you found

                                    btw. If using both forms for backward compatibility, the numbers are different "\expndtw100 \expnd20 " - twips being smaller than points.
                                    Rgds, Dave

                                    Comment


                                    • #38
                                      Good to know this about Windows Ten.
                                      Also, under Windows Seven, my code worked well with previous version of RichEdit but didn't with RichEdit50W 4.1.
                                      So finding EM_SETTYPOGRAPHYOPTIONS was necessary because I wanted to use this latest version.

                                      For twips and points, I agree, better to do the math right, 20 twips = 1 point,
                                      expnd is expressed in quarter of a points, so \expndtw5 = \expnd1, aka a ratio of five twips for one (¼)point.

                                      Comment


                                      • #39
                                        Added some comments and corrected an issue to 6 Dec 2018, 10:45 PM post,
                                        pcb = cb was needed in reRichEditToStringCallBack

                                        Comment


                                        • #40
                                          Pierre,
                                          Thanks for the ongoing effort! Here I am going to a Christmas party with the wife and I've left you home alone with the "dishes"! Thanks so much!

                                          Comment

                                          Working...
                                          X