News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

RichTextBox

Started by chemicalNova, April 07, 2005, 11:45:45 PM

Previous topic - Next topic

chemicalNova

Howdy all,

I feel a bit stupid posting on the same day again, I'm still learning. I've been able to use the FontDialog to get a font and change the contents of the whole RIchTextBox, but I want to change from 1 font to another. I know I have to use EM_SETCHARFORMAT and possibly the SCF_SELECTION value for the wParam, but I have no idea how to implement it.

Anybody able to help me?

Thanks in advance,

chem

hutch--

Chem,

Don't worry about asking another question, thats why we are here. Change the font in an edit box with the WM_SETFONT message.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

chemicalNova

Thanks Hutch.

I've been using the WM_SETFONT message, but no matter what flags I use, it changes ALL the text in the RichTextBox to the font. I want to use multiple fonts. I'm trying to make a small text editor to get the hang of things. I've tried using WM_SETCHARFORMAT and then WM_SETFONT, or just WM_SETCHARFORMAT. Either way, all the font is changed, or nothing at all.

Thanks in advance,

chem

pbrennick

Hi chemicalNova,
You are off to a good start, I see.  This is what you need to do.  Firstly, and you probably already know this, you need to highlight the text you wish to alter the formatting of.  Next, and this is very important, when you set the font you need to use the SCF_SELECTION flag in EM_SETCHARFORMAT (look it up in the win32.hlp file) to ensure that the change only will apply to the selected text.

If you have more questions, please ask.  As Hutch said, that is what we are here for.

Paul

chemicalNova

I haven't tried that as yet, but I wanted to change fonts on the fly. So, say I start typing in size 10 Courier New. I want to go, Set Font >> Choose say, FixedSys in size 12. Then I would start typing into the richtextbox again, and it would come out like this:

This is the courier New.This is the new typed text.

Is it possible? For another example:

'Visual Basic
RichTextBox1.SelFontName = "Courier New"
RichTextBox1.SelFontSize = 10
RichTextBox1.SelStart = Len(RichTextBox1.Text)
RichTextBox1.SelText = "This is the courier New."
RichTextBox1.SelFontName = "FixedSys"
RichTextBox1.SelFontSize = 12
RichTextBox1.SelStart = Len(RichTextBox1.Text)
RichTextBox1.SelText = "This is the new typed text."

Sorry if I didn't make sense in my first post. Does it kinda make sense now?

chem

pbrennick

Hi chemicalNova,

Okay, you would still use the method I showed you except you will not be selecting any text.  If you use that method the font change will occur at the 'insertion' point instead.

One more thing, if you want to preserve the formatting you are so painstakingly creating, be sure to use the .rtf extension in your fiename and make sure that, instead of using something like the following for sending the stream to your file;


invoke  SendMessage, hREdit, EM_STREAMOUT, SF_TEXT, addr EditS


you should use the following method instead:


invoke  SendMessage, hREdit, EM_STREAMOUT, SF_RTF, addr EditS


Once you do that, you are no longer saving as a 'text' file, but as a 'richtext' file.

Paul

chemicalNova

Thanks for that, woulda had to make another post for the saving part :)

But my problem still stands, I don't know how to implement it. I guess I need a code example, this is what I have:

; font dialog
invoke FontDialog,hWin,ADDR lfnt,CF_BOTH or CF_FIXEDPITCHONLY
;create font
invoke CreateFont,15,0,0,0,0,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
    PROOF_QUALITY,FIXED_PITCH or FF_MODERN,ADDR lfnt.lfFaceName
invoke SendMessage,hRichEd,EM_SETCHARFORMAT,SCF_SELECTION,ADDR charfmt
invoke SendMessage,hRichEd,WM_SETFONT,eax,0

I would of thought that WM_SETFONT would look at the flags set the line before, but obviously doesn't. Also, it only lets me change the font of the WHOLE richtextbox, once.

Any code snippets would help alot.

Sorry about this guys/gals :)

chem

pbrennick

chemicalNova,
Okay, here goes:


ChooseFonts proc hWND:HWND
    invoke GetDC, hRichEditGlobal
    mov hDc, eax

    mov cf.lStructSize, sizeof CHOOSEFONT
    push hRichEditGlobal
    pop cf.hWndOwner
    mov cf.Flags, (CF_TTONLY or CF_SCREENFONTS or CF_EFFECTS or CF_NOSCRIPTSEL)
    push offset myLogFont
    pop cf.lpLogFont
    mov cf.nSizeMin, 8
    mov cf.nSizeMax, 72
    mov cf.lpTemplateName, NULL
    mov cf.lpfnHook, NULL   

    invoke ChooseFont, ADDR cf
    .if eax == NULL
        invoke GetLastError
        mov nLastError,eax
        invoke FormatMessage,\
            FORMAT_MESSAGE_FROM_SYSTEM,\
            NULL, nLastError, NULL, ADDR szMsgBuff, 128, NULL
        invoke MessageBoxEx, NULL, ADDR szChooseFont, NULL,\
            MB_OK+MB_ICONERROR, LANG_ENGLISH
    .else
        invoke CreateFontIndirect, cf.lpLogFont
        .if eax == NULL
            invoke GetLastError
            mov nLastError,eax
            invoke FormatMessage,\
                FORMAT_MESSAGE_FROM_SYSTEM,\
                NULL, nLastError, NULL, ADDR szMsgBuff, 128, NULL
            invoke MessageBoxEx, NULL, ADDR szMsgBuff, ADDR szChooseFont,\
                MB_OK+MB_ICONINFORMATION, LANG_ENGLISH
        .endif

        invoke SelectObject, hDc, eax
        .if eax == NULL
            invoke GetLastError
            mov nLastError,eax
            invoke FormatMessage,\
                FORMAT_MESSAGE_FROM_SYSTEM,\
                NULL, nLastError, NULL, ADDR szMsgBuff, 128, NULL
            invoke MessageBoxEx, NULL, ADDR szMsgBuff, ADDR szChooseFont,\
                MB_OK+MB_ICONINFORMATION, LANG_ENGLISH
        .endif
   
        invoke ReleaseDC, hRichEditGlobal, hDc
                       
        mov cfm.cbSize, sizeof cfm
        ;mov cfm.dwMask, (CFM_ITALIC or CFM_BOLD or CFM_UNDERLINE)

        mov cfm.cbSize,60

        or cfm.dwMask, (CFM_FACE or CFM_SIZE or\
            CFM_COLOR or CFM_UNDERLINE or CFM_BACKCOLOR)

        ;Set the new typeface, preserving the previous effects.
        invoke lstrcpy, ADDR cfm.szFaceName, ADDR myLogFont.lfFaceName

        ;Set the size: Multiply by 20 to convert to twips.
        xor edx, edx
        mov ebx, 20
        mov eax, myLogFont.lfHeight
        mul ebx
        mov cfm.yHeight, eax

        push cf.rgbColors
        pop cfm.crTextColor

        ;is bold chosen?
        .if myLogFont.lfWeight == FW_BOLD
            or cfm.dwEffects, CFE_BOLD
        .else
            and cfm.dwEffects, 0FFFFFFFEh   ;turn off the bold bit
        .endif

        ;is italic chosen?
        mov ax,cf.nFontType
        and ax, 0200h
        .if ax == ITALIC_FONTTYPE
            or cfm.dwEffects, CFE_ITALIC
        .else
            and cfm.dwEffects, 0FFFFFFFDh   ;turn off the italic bit
        .endif

        ;is underline chosen?
        xor eax, eax
        mov al, myLogFont.lfUnderline
        .if eax == TRUE
            or cfm.dwEffects, CFE_UNDERLINE
        .else
            and cfm.dwEffects, 0FFFFFFFBh   ;turn off the underline bit
        .endif

        invoke SendMessage, hRichEditGlobal, EM_SETCHARFORMAT, SCF_SELECTION,\
             ADDR cfm
        .if eax == NULL
            invoke GetLastError
            mov nLastError,eax
            invoke FormatMessage,\
                FORMAT_MESSAGE_FROM_SYSTEM,\
                NULL, nLastError, NULL, ADDR szMsgBuff, 128, NULL
            invoke MessageBoxEx, NULL, ADDR szMsgBuff, ADDR szSetCharFormat,\
                MB_OK+MB_ICONINFORMATION, LANG_ENGLISH
        .endif

        ;make the push buttons sync
        mov ax,cf.nFontType
        and ax, 0200h
        .if ax == ITALIC_FONTTYPE
            .if bItalic == TRUE
            .else
                    invoke ToggleButton, hWndGlobal, IDM_ITALIC, bItalic
                mov bItalic, eax
            .endif
        .else
            .if bItalic == TRUE
                    invoke ToggleButton, hWndGlobal, IDM_ITALIC, bItalic
                mov bItalic, eax
            .endif
        .endif

        .if myLogFont.lfWeight == FW_BOLD
            .if bBold == TRUE
            .else
                    invoke ToggleButton, hWndGlobal, IDM_BOLD, bBold
                mov bBold, eax
            .endif
        .else
            .if bBold == TRUE
                    invoke ToggleButton, hWndGlobal, IDM_BOLD, bBold
                mov bBold, eax
            .endif
        .endif

        xor eax, eax
        mov al, myLogFont.lfUnderline
        .if eax == TRUE
            .if bUnderLine == TRUE
            .else
                    invoke ToggleButton, hWndGlobal, IDM_UNDERLINE, bUnderLine
                mov bUnderLine, eax
            .endif
        .else
            .if bUnderLine == TRUE
                    invoke ToggleButton, hWndGlobal, IDM_UNDERLINE, bUnderLine
                mov bUnderLine, eax
            .endif
        .endif

    .endif
    xor eax, eax
    ret
ChooseFonts endp


As you can see, there is a lot involved here.  This handles a lot more than just setting the font and fontsize, it handles bold, italics and underline, etc.  Look at the SCF_SELECTION part.

Paul

chemicalNova

Thanks pbrennick. This looks more like what I was after. I had no idea it would be so big, but I thank you for it. I still get quite a few errors, but I'm confident I can declare most of the variables you didn't.

Thanks again,

chem

pbrennick

chemicalNova,
Attached is the source with all the declarations.  It is a pretty basic example and needs work, like I need to do a SetFocus after the font is changed so you do not have to click in the window after changing fonts.  I can do that if you want, just pretty busy right now.

Paul


[attachment deleted by admin]

chemicalNova

pbrennick:

I can't tell you how helpful that is. Thank you so much! :)

*hugs*
*kisses*

chem