This tutorial shows how to use the Rich Edit DLL to design an Edit window that high lights predetermined keywords. It is an excellant example and I want to use it (or portions of it) to build my own editor but the one thing I dont like is the font associated with the Edit window. Can anyone here post something on how to change the font to say something like Fixedsys at 9 points. I like this font better because it is not a true type font and I like characters to align up on the text lines.
Hi Robert,
You first have to create a font with the specified characteristics (API function CreateFont) and then you send a WM_SETFONT message to the rich edit control.
Ramon
Robert,
Courier might be a more visually appealing font than fixedsys and will do what you want. The secret is to select a nonproportional font which both of them are. I use Courier as the default in my editor because I like things to line up also.
inv equ invoke
FontName DB 'Courier', 25 Dup (0) ; 32 bytes max (including ASCIIZ terminator)
FontHeight DD - 13 ; -12=9pt., -13=10pt., -15=11pt., etc.
FontWeight DD 400 ; 400=normal, 700=bold
PointSize DD 100 ; PointSize*10, actually
and it is created in this manner...
; Create font
inv lstrcpy, Offset lfnt.lfFaceName, Offset FontName ; Get fontname
Mov Eax, FontHeight ; Get font height
Mov lfnt.lfHeight, Eax ; Store the font height in the logfont structure
Mov Eax, FontWeight ; Get font weight
Mov lfnt.lfWeight, Eax ; Store the font weight in the logfont structure
inv CreateFontIndirect, Offset lfnt ; Create the font
Mov hFont, Eax ; Store it
inv SetFormat, hREd
Instead of WM_SETFONT I chose to use the following so I could set tabstops, etc.:
SetFormat Proc hWin:DWord
;---------------------------------------;
Local chrg1:CHARRANGE ; Structure
Local chrg2:CHARRANGE ; Structure
Local pf:PARAFORMAT2 ; Structure
Local cf:CHARFORMAT ; Structure
Local tp:DWord ; Scratch variable
Local buffer[16]:Byte ; Temporary buffer
Local pt:POINT ; Pixel point
Local hDC:HDC ; Device context
;
; Save modification state
inv SendMessage, hWin, EM_GETMODIFY, 0, 0 ; Get document state
Push Eax ; Save it
; Save selection
inv SendMessage, hWin, EM_EXGETSEL, 0, Addr chrg1 ; Get range of possible selection
inv SendMessage, hWin, EM_HIDESELECTION, TRUE, 0 ; Save it by hiding it
; Select all text
Mov chrg2.cpMin, 0 ; Get start of document
Mov chrg2.cpMax, -1 ; Get end of document
inv SendMessage, hWin, EM_EXSETSEL, 0, Addr chrg2 ; Select all of the text in the control
; Set font charset
Mov cf.cbSize, SizeOf cf ; Get size of the structure
Mov cf.dwMask, CFM_CHARSET Or CFM_FACE Or CFM_SIZE Or CFM_COLOR ; Set the attribute mask
Mov Al, lfnt.lfCharSet ; Get current character set
Mov cf.bCharSet, Al ; Store it in the structure
Mov Al, lfnt.lfPitchAndFamily ; Get character styles
Mov cf.bPitchAndFamily, Al ; Store it in the structure
inv lstrcpyn, Addr cf.szFaceName, Offset lfnt.lfFaceName, LF_FACESIZE
Mov Eax, lfnt.lfHeight ; Get height
Neg Eax ; Multiply by -1
Mov Ecx, 15 ; Get multiplier
Mul Ecx ; Multiply by 15
Mov cf.yHeight, Eax ; Save the result
Mov Eax, rgb ; Get foreground color
Mov cf.crTextColor, Eax ; Save it
inv SendMessage, hWin, EM_SETCHARFORMAT, SCF_SELECTION, Addr cf ; Set character format
; Get tab width
inv GetDC, hWin ; Retrieves a handle of a device context (DC) for the edit control
Mov hDC, Eax ; Save the DC
inv SelectObject, hDC, hFont ; Selects an object into the specified device context
Push Eax ; Save it
Mov Eax, 'WWWW' ; Get 4 of the largest character in the set
Mov DWord Ptr buffer, Eax ; Put it in the buffer
inv GetTextExtentPoint32, hDC, Addr buffer, 4, Addr pt ; Computes the width and height of the specified string of text
Pop Eax ; Restore the font
inv SelectObject, hDC, Eax ; Reset the device context
inv ReleaseDC, hWin, hDC ; Release the device context resources
Mov Eax, pt.x ; Save the x coordinate (size)
Mov Ecx, TabSize ; Get current tabsize
Mul Ecx ; Get pixel value
Mov Ecx, 15 ; Get multiplier
Mul Ecx ; Multiply by 15
Shr Eax, 2 ; Divide by 2
Mov tp, Eax ; Save the resulting tab points (in pixels)
; Set tab stops
Mov pf.cbSize, SizeOf pf ; Get size of the structure
Mov pf.dwMask, PFM_TABSTOPS ; Set mask
Mov pf.cTabCount, MAX_TAB_STOPS ; Set tab count
Xor Eax, Eax ; Clear the accumulator
Xor Edx, Edx ; Clear the data register
Mov Ecx, MAX_TAB_STOPS ; Get tab count
J001: Add Eax, tp ; Plus pixel count
Mov DWord Ptr pf.rgxTabs[Edx], Eax ; Store tab stop in the structure
Add Edx, 4 ; Get next tab stop
Loop J001 ; Build complete tab stop table
inv SendMessage, hWin, EM_SETPARAFORMAT, 0, Addr pf ; Store this information in the edit control
; Restore modify state
Pop Eax ; Restore the document state
inv SendMessage, hWin, EM_SETMODIFY, Eax, 0 ; Reset the edit control to how it was originally
; Restore selection
inv SendMessage, hWin, EM_EXSETSEL, 0, Addr chrg1 ; Get positions of any text that was selected
inv SendMessage, hWin, EM_HIDESELECTION, FALSE, 0 ; Make it visible
Ret ; Return
;---------------------------------------;
SetFormat EndP
I hope you find this useful.
Paul
pbrennick,
Yes, I like Courier also. I picked Fixedsys only because it is what Notepad uses and I kind of like the darkness of the font and Courier is a light weight font. Either one is OK, though.
Ok, I understand the data; FontName, FontHeight, FontWeight, and PointSize and the code. What I am not understanding is where do you get the lfnt.????? stuff? Like lfnt.lfFaceName and all the others. Also, I get undefined on 'hREd', 'rgb' and 'TabSize'
Robert,
Here are the missing pieces, sorry, I grabbed it out of my editor program.
TabSize DD ? ; Store tabsize (will be set to 4)
hFont DD ? ; Handle for the font goes here
hREd HWND ? ; Handle of the edit control goes here
lfnt LOGFONT <> ; For CreateFontIndirect
If yoiu have any more questions, just ask,
Paul
Robert,
I downloaded the tutorial and took a peek at it. If you are following his methods, then change all occurences of hREd tohRichEdit and delete the hREd declaration. That will make sue it all works.
Paul
Paul,
You seem familiar with RichEdit controls. Would you know how to print the WYSIWYG content of such controls. I can't find any decent tutorial on that subject and the Win32 Programmer's Reference is far from enlightning.
Raymond
Hi Raymond,
I grabbed this from NaN, it is what I use a reference when I need to print something...
Do_Print PROC hWnd:DWORD, wParam:DWORD, lParam:DWORD
LOCAL memdc :DWORD
LOCAL hbmp :DWORD
LOCAL bmp :BITMAP
; Initialize the Print Dialog
; --===============================================
mov yP, 0 ; Start of page..
jmp @F
FontMS db "MS Sans Serif",0
@@:
; Initialize the Print Dialog
; --===============================================
mov PD.lStructSize, SIZEOF PD
mov eax,hWnd
mov PD.hwndOwner, eax
mov eax,hInstance
mov PD.hInstance, eax
mov PD.Flags, PD_RETURNDC ; Return Users DC choices
; Show the Print Dialog Box!
; --===============================================
invoke PrintDlg, offset PD
cmp eax, FALSE
je Done
; IF you specify the PD_RETURNDC value in the Flags member of the PRINTDLG structure and the user
; selects Print To File from the Print dialog box, you can use the DC returned in the hDC member
; of the structure to generate output, but only after you prepare the file for output by specifying
; the name of the file in the lpszOutput member of the DOCINFO structure and calling the StartDoc function.
; Check Get the Printed X+Y extence..
; --===============================================
invoke GetDeviceCaps, PD.hDC, HORZRES
shr eax, 1
mov COLUMN_2, eax ; 2 columns per page
invoke GetDeviceCaps, PD.hDC, VERTRES
shr eax, 6
mov LINE_WIDTH, eax ; 64 Lines / page
mov eax,LINE_WIDTH
mov COLUMN_1,eax
; Create A Printer Font..
; --===============================================
invoke lstrcpy, addr LF.lfFaceName, addr FontMS
mov eax,LINE_WIDTH
mov LF.lfHeight,eax
mov LF.lfWeight, 600
invoke CreateFontIndirect, ADDR LF
mov pFont, eax
; Set up the Document Info Structure
; --===============================================
mov DOC.cbSize, SIZEOF DOC
mov DOC.lpszDocName, offset DocTitle
mov DOC.lpszOutput, NULL
mov DOC.fwType, NULL
; Start the Doc..
; Ensures proper print order of pages..
; --===============================================
invoke StartDoc, PD.hDC, offset DOC
; Start the Page..
; Prepares the printer driver to accept data.
; --===============================================
invoke StartPage, PD.hDC
; Load a Printer Font..
; --===============================================
invoke SelectObject, PD.hDC, pFont
; Print the lines here
; --===============================================
jmp @F
; This is an example
szTestMessage db "This is a test",0
szTestMessage2 db "This is a test2",0
@@:
LinePrint OFFSET szTestMessage
LinePrint OFFSET szTestMessage2
invoke CreateCompatibleDC,PD.hDC
mov memdc,eax
invoke LoadBitmap,hInstance,10000
mov hbmp,eax
invoke SelectObject,memdc,hbmp
push eax
invoke GetObject,hbmp,SIZEOF bmp,ADDR bmp
invoke BitBlt,PD.hDC,0,0,bmp.bmWidth,bmp.bmHeight,memdc,0,0,SRCCOPY
pop eax
invoke SelectObject,memdc,eax
invoke DeleteDC,memdc
invoke DeleteObject,hbmp
; Do the End of Page (feed out the paper)
; --===============================================
invoke EndPage, PD.hDC
invoke EndDoc, PD.hDC
invoke DeleteDC, PD.hDC
Done:
ret
Do_Print ENDP
Don't forget to destroy the Font that
you create after finish with that.
Manos.
Repost?
I just implimented printing in an app I've written. In the app, reports are generated in Rich Text Format (RTF), and Printed without user interaction, Viewed with option to print, View with only option to close.
RTF was used to enabled viewing and printing outside of my app, and to allow emailing the reports.
I originally used WordPad to view and print, but with a report of 2 or more pages, the page breaks (\page) were not handled. I then used a different editor--Jarte--which worked great, but I sometimes had difficulty automated the file open/print operation.
I then tried the RichEdit control, but the page break was still not handled, and on different printers, page feeds would happen at different places.
Then using Chib777's code from the Print/Preview function released for Hutch--'s QEditor, I was able to "Roll my own" Now I can simulate page breaks, print in portrait or landscape, collate. The only thing I haven't figured is how to start printing the last page first.
If there is any interest, I'll post some code and explaination. Just give me 1 or 2 days, I have a deadline looming! :eek <- too much coffee!
farrier
farrier,
Any time you post code to this forum, you improve on the usefulness of this forum. :U
Paul
Robert,
Manos reminds me of something I forgot to tell you. Make sure you add the following message to your message processing section.
.ElseIf Eax == WM_DESTROY ; Destroy the window
inv SavToRegistry ; Store any changes in the Registry, if you don't need this just remove it
inv DeleteObject, hFont ; Delete the font
inv PostQuitMessage, NULL ; Tell Windows that this thread has made a request to terminate (quit)
SetFormat cleans up its own created resource (hDC) so that hFont is the only resource I have introduced into your code that needs to be cleaned up.
Thank you, Manos for keeping me on the straight and narrow.
Paul
Quote from: donkey on December 28, 2004, 05:17:46 AM
Hi Raymond,
I grabbed this from NaN, it is what I use a reference when I need to print something...
Thanks donkey. I have used that also but I am still looking for WYSIWYG printing. farrier may provide what I need. Should be most interesting.
Raymond
Raymond,
Try mine:
; Include Files
; --------------------------------
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\gdi32.inc
;
; Libraries
; --------------------------------
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\gdi32.lib
ErrorMsg PROTO
PrintProc PROTO
MOVmd Macro Var1, Var2
Push Var2
Pop Var1
EndM
MsgBox Macro Resource:req, Title: = < ERROR > , Flags: = < MB_OK Or MB_ICONEXCLAMATION >
Mov Eax, Resource
Lea Ebx, Title
Mov Ecx, Flags
Call ErrorMsg
EndM
inv equ invoke
ERROR_NO_SELECTION Equ 30012
.data
;---------------------------------------
FontName DB 'Courier', 25 Dup (0) ; 32 bytes max (including ASCIIZ terminator)
; Printer stuff
;---------------------------------------;
mB DD 0 ; Bottom margin of printed page
mL DD 0 ; Left margin of printed page
mR DD 0 ; Right margin of printed page
mT DD 0 ; Top margin of printed page
RTwips1000 Real10 1.44 ; Twips constant
w1 DD 0 ; Scratch variable used when calculating margins
pTitle DB 'GeneSys Editor', 0 ; Document Title
Sel DD 0 ; Flags a 'Range' type print job, currently unused
xPerInch DD 0 ; Width of printable area
yPerInch DD 0 ; Height of printable area
PrtHead DD 1
PrtColor DD 0
cnt DD 0
szSelect DB 'Selected Text!', 0
szWork DB 256 Dup (?), 0
szNULL DB 0 ; Null value
.data?
;---------------------------------------
hREd HWND ? ; Handle
hInstance DD ? ; Handle
hWnd HWND ? ; Handle
; Structures used by the Printer Routines
;---------------------------------------
doci DOCINFO <?> ; Docinfo (printing support)
fr_1 FORMATRANGE <?> ; For EM_FORMATRANGE
pd PRINTDLG <?> ; Print
rect_1 RECT <?> ; Rectangle
charF CHARFORMAT2 <?> ; For EM_GETCHARFORMAT/EM_SETCHARFORMAT
cr CHARRANGE <?> ; Character range
PrintProc Proc
;---------------------------------------
Local Chg:DWord, TextSize
Local cf:CHOOSEFONT ; Structure
;
inv SendMessage, hREd, EM_GETMODIFY, 0, 0
Mov Chg, Eax
Push cf.rgbColors
Mov cf.rgbColors, 0
inv SendMessage, hREd, EM_SETBKGNDCOLOR, 0, 00FFFFFFH
Pop cf.rgbColors
Cmp PrtColor, 1
Je StartPrt
inv SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
inv SendMessage, hREd, EM_SETSEL, -1, 0
Mov charF.dwMask, CFM_FACE Or CFM_SIZE Or CFM_COLOR
Mov charF.crTextColor, 0
inv lstrcpy, Offset charF.szFaceName, Offset FontName
inv SendMessage, hREd, EM_SETCHARFORMAT, SCF_ALL, Offset charF
inv SendMessage, hREd, EM_EXSETSEL, 0, Offset cr
StartPrt:
Mov cnt, 0
Mov pd.lStructSize, SizeOf pd
Mov Eax, hWnd
Mov pd.hwndOwner, Eax
Mov Eax, hInstance
Mov pd.hInstance, Eax
Mov pd.Flags, PD_RETURNDC
inv PrintDlg, Offset pd
Cmp Eax, FALSE
Je PrtRet
Mov Eax, pd.Flags
Mov Ebx, Eax
And Ebx, 000000FFH
Mov Sel, Ebx
inv SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
Mov Eax, cr.cpMax
.If Eax > cr.cpMin && Sel != 1
MsgBox ERROR_NO_SELECTION, szSelect, MB_YESNO Or MB_ICONQUESTION
Cmp Eax, IDNO
Je PrtRet
.EndIf
Mov doci.cbSize, SizeOf doci
Mov doci.lpszDocName, Offset pTitle
Mov doci.lpszOutput, 0
Mov doci.fwType, 0
Mov Eax, pd.hDC
Mov fr_1.hdc, Eax
Mov fr_1.hdcTarget, Eax ;0
inv GetDeviceCaps, fr_1.hdc, LOGPIXELSX ; Number of pixels per logical inch along the screen width.
Mov xPerInch, Eax
inv GetDeviceCaps, fr_1.hdc, LOGPIXELSY ; Number of pixels per logical inch along the screen height.
Mov yPerInch, Eax
Mov Eax, mL ; Min is 360
Mov rect_1.left, Eax
Mov Eax, mT ; Min is 360
Mov rect_1.top, Eax
.If PrtHead
Add rect_1.top, 420 ; 360
.EndIf
inv GetDeviceCaps, fr_1.hdc, HORZRES ; Width, in pixels, of the screen.
Mov Ecx, 1440
Mul Ecx
Div xPerInch
Mov rect_1.right, Eax
Mov Eax, mR ; Min is 360
Sub rect_1.right, Eax
inv GetDeviceCaps, fr_1.hdc, VERTRES ; Height, in raster lines, of the screen.
Mov Ecx, 1440
Mul Ecx
Div yPerInch
Mov rect_1.bottom, Eax
Mov Eax, mB ; Min is 302
Sub rect_1.bottom, Eax
Mov Ecx, 16
Mov Edi, Offset fr_1.rcPage
Mov Esi, Offset rect_1
Cld
Rep Movsb
inv StartDoc, pd.hDC, Offset doci
inv SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
Mov Eax, cr.cpMin
Mov Ebx, cr.cpMax
.If Ebx > Eax && Sel == 1
Mov fr_1.chrg.cpMin, Eax
Mov fr_1.chrg.cpMax, Ebx
Mov TextSize, Ebx
.Else
inv SendMessage, hREd, EM_HIDESELECTION, 1, 0
Mov cr.cpMin, 0
Mov cr.cpMax, -1
inv SendMessage, hREd, EM_EXSETSEL, 0, Offset cr
inv SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
MOVmd fr_1.chrg.cpMin, cr.cpMin
Mov fr_1.chrg.cpMax, -1
MOVmd TextSize, cr.cpMax
Mov cr.cpMin, 0
Mov cr.cpMax, 0
inv SendMessage, hREd, EM_EXSETSEL, 0, Offset cr
inv SendMessage, hREd, EM_HIDESELECTION, 0, 0
.EndIf
prtloop:
inv StartPage, pd.hDC
Cmp Eax, 0
Jle prtabort
Mov Ecx, 16
Mov Esi, Offset rect_1
Mov Edi, Offset fr_1.rc ; Actual print page dimensions
Cld
Rep Movsb
inv SendMessage, hREd, EM_FORMATRANGE, TRUE, Offset fr_1 ; Print page
Mov fr_1.chrg.cpMin, Eax
inv EndPage, pd.hDC
Cmp Eax, 0
Jle prtabort
Mov Eax, fr_1.chrg.cpMin
Cmp Eax, 0
Jle prtdone
Cmp Eax, TextSize
Jl prtloop
prtdone:
inv SendMessage, hREd, EM_FORMATRANGE, 0, 0
inv EndDoc, pd.hDC
inv DeleteDC, pd.hDC
Jmp PrtRet
prtabort:
inv AbortDoc, fr_1.hdc
PrtRet: Ret
;---------------------------------------
PrintProc EndP
; _____________________________
;| |
;| Generate error message |
;| eax = message # to display |
;| ebx = Title |
;| ecx = MessageBox Flags |
;|_____________________________|
;
ErrorMsg Proc
;---------------------------------------;
Push Ecx ;
Push Ebx ; Save these for after LoadString call
Push LengthOf szWork ; Size of our buffer
Push Offset szWork ; Buffer to load string into
Push Eax ; Resource #
Push hInstance ; Instance
Call LoadString ; Load the tip from STRINGTABLE
Cmp Eax, 0 ; Did we get a string?
Jne Error1 ; Yes, continue
Lea Eax, szNULL ; Null string
Error1: Push Offset szWork
Push 0
Call MessageBox
Ret
;-------------------------------------
ErrorMsg EndP
I have included all the variable and structures needed.
call PrintProc
The above line is used to call the procedure
Paul
Hi Paul.
Thanks for your sample.
Well, using your sample code I finally got most of it to work but there are a couple of things that I am still in the dark about.
First, I found out about the lfnt.?????? stuff and already created a LOGFONT structure.
Second, After I took a guess about 'hREd' I changed it to 'hRichEdit' and that solved that problem.
Third, as far as the 'rgb' variable I used the one in the Tutorial 'TextColor'
OK, now the problems:
You say that 'TabSize' will be set to 4. I cannot find anyplace in the code where this variable is
initialized to any value.
Here are some things that I do not understand in your proc 'SetFormat'
At the Create font section you initialize the LOGFORMAT structure for the lfnt.lfHeight and the
lfnt.lfWeight but you do not do anything with the other elements of the structure. I am assuming that
it doesnt matter.
Now, down at the section where you set the charset I see that you have the following lines of code:
'
'
'
mov al, lfnt.lfCharSet ; Get current character set
mov cf.bCharSet, al ; Store it in the structure
mov al, lfnt.lfPitchAndFamily ; Get character styles
mov cf.bPitchAndFamily, al ; Store it in the structure
.
.
However, I cannot find anywhere where you have previously initialized lnft.lfCharSet nor lfnt.lfPitchAndFamily
but you are moving their contents into the CHARFORMAT structure.
And now the final and most important problem. I have been able to get the font and point size I like but no
matter what I do I am unable to remove the BOLD look to any font that I decided to use. FIXEDSYS comes
out looking very thick and black, so much that it is ugly. Why wasn't the font weight (400 for normal) effective
when the font was created? Where in the other structures does one control whether the font is bold or not.
I can change the font to Italics, Underscore, Strikeout but I cannot get rid of that bold look.
Robert,
There are 3 structures that are important for font setting. Giving you a portion of my code is causing real problems because SetFormat is relying on some of those structures being initialized at the start of the program based on initial settings if it is a first run or data from the registry if not a first run.
What I am going to do is attach my complete project to this posting so you can see how I initialized the structures. If the font looks too bold something is wrong in one of the structures.
If you play with the part of my editor that is used to build projects, remember that it expects the .rc and .asm files to have the same names, such as test.asm and test.rc
Also, I have not written the code for console builds yet, that will be in the next few days ahead and then the project will be complete except for updating the docs.
Once you have got the info from my project that you need, feel free to continue to ask questions. It sounds like you are determined to learn, that attitude will get you far. Keep it up.
Paul
[attachment deleted by admin]
Paul,
Thanks for your code on WYSIWYG printing. That may be what I was looking for. I'm going to experiment with it to fit my specific needs. (I had previously attempted that route, but failed because I couldn't understand some of the requirements.)
Raymond
Raymond,
Have you written a procedure that does the page setup? Sets margins, orientation, etc.
Paul
Paul,
That was several months ago. At that time, I didn't really understand what was required in the two DC parameters, nor how to fill the two RC parameters, nor how to use the EM_FORMATRANGE message. Your code should now help me in setting things up properly.
Thanks
Raymond
Hi Paul,
OK, I d/l your source and have been going over it briefly. My first impression was that this is one great looking and functional editor and the code is laid out real professional like. Your style of coding is nicely organized, extremely (and well done) commented, and easy to follow. I wish the other programmers where I work would follow your style.
Well, before I start to get into it I have encountered something that I am not sure what is going on. It appears that the font selection from the drop down font dialog box doesn't seem to work as I would expect it to. As I select different fonts it doesn't change the font in the text window. Now, sometimes it will but in most cases it wont. I toggled back and forth with several different font names and style (bold, italic, regular, etc) but the text remains the same in the text editor window. Also, I selected Wingdings but the font remained the same as it was but later when I changed from Wingding to some other font the Wingding font appeared. At one time I had selected MS Sans Serif and the font did change but it wasn't MS Sans Serif, I don't know what font it was but I know it wasn't MS San Serif. Now, whatever it was, I then went back and changed it from Regular to Bold and then the Wingding font appeared. Are you aware of any problems with this feature of the program.
One thing that I noticed in all font selections was that none of them ever appeared as bold when I selected the bold style.
Ok, I went into the code and commented out the below two lines in WndProc @ WM_INITDIALOG
inv GtFrmRegistry ; Load settings from Registry
inv LoadMRUFiles ; Load MRU from Registry
Now when I play around with the fonts from the dialog box they do change to the fonts I select, but still I am unable to change the style. It appears that the Regular, Italic, Bold, Bold Italic styles are ignored.
Hi Paul,
Me again. Here is something that is somewhat confusing me.
In the Registry I found the following:
HKEY_LOCAL_MACHINE\Software\Editor+
Background Color 0x00ffffff (16777215)
Character Font "Courier"
Font Height 0xfffffff3 (4294967283)
Font Weight 0x00000190 (400)
MRU_File1 "C:\Assembly32\GeneSys\GeneSys.asm"
MRU_FIle2 ""
MRU_FIle3 ""
MRU_FIle4 ""
MRU_FIle5 ""
Point Size 0x00000064 (100)
Text Color 0x00000000 (0)
Which is what your program retrieves at WndProc WM_INITDIALOG
.
.
inv GtFrmRegistry ; Load settings from Registry
'
''
So, it should load the font stated in the registry, 'Courier', but it doesn't. It loads a font called 'Lucida Handwriting' which is one if the fonts I was playing around with earlier. As it turns out I put that name in the below variable:
FontName DB 'Lucida Handwriting', 32-18 Dup (0) ; 32 bytes max (including ASCIIZ terminator)
My question is wouldn't the information in the registry superceed any hard coded names in the program? Otherwise, what is the point of saving the font name in the registry if the program ignores it and uses the font name in the variable? I haven't studied the code so maybe there is something that I am overlooking.
Robert,
I am going to repair the registry and stausbar update problem that you discovered and then repost the project. If you save your data as an rtf file it will then preserve the formatting you placed on the data. But there is definitely a problem as I just stated.
Paul
Quote from: pbrennick on December 29, 2004, 09:32:17 PM
Robert,
I am going to repair the registry and stausbar update problem that you discovered and then repost the project. If you save your data as an rtf file it will then preserve the formatting you placed on the data. But there is definitely a problem as I just stated.
Paul
You know, that never entered my mind. So, you are saying that a saved file as an RTF will preserve the formatting (incl. font, font size, etc). OK, I agree but during my playing around with the editor I never saved anything.
Here is what I find:
In the below snippit FontName = 'Ludica Handwriting' and is copied to lfnt.lfFontName. This is the first occurance of using FontName.
WndProc proc
'
'
inv lstrcpy, Offset lfnt.lfFaceName, Offset FontName ; Get fontname
'
'
In the below snippit FontName = 'Ludica Handwriting'. This is the 2nd occurance of FontName used.
ShowFont proc
.
.
inv lstrcpy, Addr Stuffing, Addr FontName ; Build the message
'
'
In the below snippit FontName and szFontName = 'Ludica Handwriting' on the first time into this proc.
On the second time into this proc FontName and szFontName = 'Courier'.
This is the 3rd and 4th time FontName is used.
GtFrmRegistrt proc
.
.
inv lstrcpy, Addr FontName, Addr szFontName ; Store FontName
'
'
/code]
So, the only other variable is lfnt.lfFontName which contained 'Ludica Handwriting'
In the below line lfnt.lfFaceName is 'Ludica Handwriting'. This is why it doesn't put the font from the registry into the cf structure.
Either you need to use FontName or somewhere else in the code you need to initialize lfnt.lfFaceName with the name of the font
from the registry.
SetFormat proc
.
.
inv lstrcpyn, Addr cf.szFaceName, Offset lfnt.lfFaceName, LF_FACESIZE
'
'
There is a problem and I am working on it. I may not be able to get a solution for several days because of a personal problem. As it is the version I have on my machine loads and saves to the registry correcly and the statusbar correctly shows the current font. The only problem I have left is initializing the font at the beginning of the run. I can get it to load something but something is still wrong.
Be patient, Rome wasn't built overnight,
Paul
Hi Paul,
If you are loading and saving a font to the registry why not use raw data and just save the structure directly. Yes even in MASM syntax :)
FontSubKey DB "Software\SomeCompany\SomeApp\Preferences",0
userfontvalue DB "UserFont",0
; If no font entry is found Tahoma 10pt will be the default
FontStruct LOGFONT <-13,0,0,0,900,FALSE,FALSE,0,0,0,0,0,0,"Tahoma">
SaveFontToReg proc
LOCAL hFontKey :DWORD
LOCAL Disposition :DWORD
invoke RegCreateKeyEx,HKEY_CURRENT_USER,OFFSET FontSubKey,0,0, \
REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,0, \
ADDR hFontKey,ADDR Disposition
invoke RegSetValueEx,[hFontKey], OFFSET userfontvalue, 0, REG_BINARY, \
OFFSET FontStruct, SIZEOF LOGFONT
invoke RegCloseKey,[hFontKey]
ret
SaveFontToReg endp
LoadFontFromReg proc
LOCAL hFontKey :DWORD
LOCAL uDataCode :DWORD
LOCAL nBytes :DWORD
mov [nBytes],SIZEOF LOGFONT
invoke RegOpenKeyEx,HKEY_CURRENT_USER,OFFSET FontSubKey, \
0,KEY_READ,ADDR hFontKey
or eax,eax
jnz @F
invoke RegQueryValueEx,[hFontKey],OFFSET userfontvalue,0, \
ADDR uDataCode,OFFSET FontStruct,ADDR nBytes
invoke RegCloseKey,[hFontKey]
@@:
ret
LoadFontFromReg endp
I wouldn't do it that way because you wind up with the following registry entry:
UserFont F3 FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 84 03 00 00 00 00 00 00 00 00 00 00 54 61 68 6F 6D 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
.....and it makes it too difficult to know what it is by looking at the entry in the registry. I like to see each key and it's value so if I wanted to modify the registry I
would know how to do it.
Donkey,
Thamks for the information, I will play with it even though the registry load/save is now correct in the nwest version that has not been posted yet. I am going crazy trying to find out ehat is wrong with the initial font creation which uses the data from the registry. I am using a MessageBox to debug and the fourth quadrant of the statusbar shows basic information about the default font. What is driving me crazy is that if I load the font dialog and then close it without any changes all is fixed and the font displays correctly. Please note that although I am using the RichEdit control I only am using it for the ability to load huge files like the Bible text. The fact that opening the dialog and then closing it is leading me to believe that maybe I should initialize the CHOOSEFONT structure.
Paul
Paul
Robert,
The font problem is solved. Ramon gently reminded me that lfnt.lfCharset needs to be set correctly. Stupid oversight on my part and Ramon rocks! I have a small issue with text color not being set correctly after the font dialog runs and I am not recreating the font after the window is destroyed by clicking on New in the menu. As you probably know, this is why clicking on New causes the font to switch to Tahoma which is the default font for that control. These are simple fixes and when I have completed them, I will repost the code in Manos' subforum called Windows Projects, probably tomorrow or Saturday at the latest because of my personal problem. Your critique of my code has caused it to become a better program and I thank you very much for your guidance and wish you good fortune in your future programming endeavors. In the future let's continue this discussion in Manos' subforum, okay? I would encourage you to post your efforts in Manos' subforum, as well, when you are ready. That way we can continue to help you along.
Paul
EDIT: TextColor is repaired, one to go!
With some help of those who posted replies I finaly got the sample code in Tutorial 35 to use the font of my choise plus after battleing and pounding my head against the desk I also figured out how to change the font from BOLD to not BOLD. The only problem is that I have really no idea or conception of what I did and that really bugs me because it is not good enough to just be able to do something, I have to know the how and why but for now as long as it does what I want I will leave it as such and maybe later as I learn more I will find out then how all this stuff works.
Robert,
It takes years, and remember, debugging is a way of life from now on. It is not a failing, it is justhard for us to think the way a computer does. Every success will give you the desire to go on.
Paul
Here is the code I promised for printing an RTF file. This program uses KetilO's most excellent RadASM IDE and uses the RichEdit template to get things going. I made some small modifications to the RTF format instead of plain text. I added 8 new procedures which do the work:
mov landscape, 0
mov NumOfCopies, 1
call CreateMasm32RTF
call ChangeBP ;change \page to *page to simulate breaks
call DisplayRTFFile
call GetPrinterInfo
call GetPageInfo
call FormatScreenLikePrinter
call PrintFile
call UnChangeBP ;change *page back to \page
CreateMasm32RTF creates the new demo RTF file.
ChangeBP searches the RTF file for page breaks, and changes \page to *page, because the RichEdit control doesn't handle page breaks.
DisplayRTFFile streams the RTF file into the RichEdit control
GetPrinterInfo gives us control of the printer, Landscape/Portrait, # of copies, Collate
GetPageInfo gets info about page dimensions and sets user defined margins
FormatScreenLikePrinter makes the RichEdit control output resemble the printer output
PrintFile prints the RichEdit control contents, handling page breaks "Properly" I had to add a few additionl checks to handle pages with more than one page worth of content that does not have a page break.
UnChangeBP changes the *page back to \page
HTH
farrier
[attachment deleted by admin]
I downloaded your project, RTFPrint. Upon observing the source code in RTFPrint.asm I noticed that it has
a very close resemblance to the source code that Paul posted earlier. As a matter of fact it has exactly
the same function calls. I have to conclude that both projects came from the same origin. Also, upon
running RTFPrint.exe I noticed that the same problem occurs in the font dialog box. I can change the
font name but cannot change the font styles. Also, when the application first comes up it I look at the
font dialog box and it says that the current font is Courier New, Regular at 9 points. When I try to change
the point size to 10 and click on OK the font actually gets smaller rather than larger.
Another problem is that when the application starts up it automatically invokes the printer option.
I am not 100% sure but I think one of the problems that occur in both projects is the usage of the
CHARFORMAT structure. There are no provisions in this structure to change the font styles. However, I
changed it to CHARFORMAT2 which does have a member element to allow the font style to be changed.
QuoteI noticed that it has a very close resemblance to the source code that Paul posted earlier. As a matter of fact it has exactly
the same function calls. I have to conclude that both projects came from the same origin.
As farrier said in his post, he is using Ketil Olsen's RadASM and the RichEdit template that comes as part of the demo package for RadASM.
Donkey
Robert Collins,
All I was trying to show was how I have managed to print an RTF file, and manage the Landscape/Portrait, Number of copies, and Collate capabilities. The procedures I added were all added to the end of the WM_INITDIALOG handler of the WndProc proc.
I haven't looked at pbrennick's code, but will soon. His code may help me further my efforts.
The only thing I use the RichEdit control for is to display the contents of the RTF file. This is not an editor, just a demonstration of how to print an RTF file with no user interaction. No effort was made to change or add fonts to the RTF file. In order to add fonts, you would add them to the rtf1 variable and then add the \fs codes to the RTF file content when you want to change fonts or type sizes.
Sorry for any confusion.
farrier
I cannot speak for anyone else, but I do not copy other peoples code. I may use it as a base to do my own thing and might even use portions that can really only be done one way. Since there are only so many ways to skin a cat, similarities can creep in. If you become concerned about these things, then you would have troubles using code frome libraries, etc.This is of no real concern and can be funny when an error in documentation causes several peoples code to hiccup at the same time. As far as Print goes, I was actually working with Ewayne Wagner about this issue several years ago and I got a lot of advice from him on how to do that. He also gave me some excellent help about the Splash screen. I was having trouble trying to get it to center to the parent and not to the screen. He is a good coder and was a lot of help.
When someone reverses someones commercial applications to make money from someone elses efforts, well, that is not only worg, it is against the law. Every thing I make is freeware and any one can use it or portions of it and don't worry if your print routine winds up looking like mine. It is no big deal. The only requirement I used to make (and may do so again) is that if you assume ownership of my code by improving upon it, you should also assume ownership of any support mechanism. This is because I don't want to have to trace down every change that has been made. Once it is modified, I will deny owning it.
Paul
Robert,
Continue to ask questions and I will continue to help as we all will (we cross posted so I want to make sure you understand).
Paul
I was only pointing out that due the exactness of both projects they must have the same origin point and therefore, unless one is corrected, have the same identical problems. As it turned out, both projects did have the same problem with the font dialog box. I was looking for an answer to my original question so when one or more persons post sample code or even allow downloads that in the end, does not really provide an answer to my question (although very helpful in other aspects) I want you to know that I am very appreatiative for your help and anyone else's help even though I was unable to get an answer to my original question. It is of no concern how anyone obtains source code for any project; I use code snippits from anywhere I can get my hands on it if it is going to make my project work. If two people send me the same stuff to try and help me and both have the same problem then in essence I cannot use either but I believe it should be made known in an effort to eliminate duplicate problems.
I am still working on the original problem which involves trying to get the correct way to change the font styles. I was somewhat successful but it didn't work in all cases and that was when I changed the CHARFORMAT structure to CHARFORMAT2. It worked in one program (I beleive it was in Tutorial 33) but does not work in Tutorial 35 which is the one I want it to work in.
Robert,
You have my most recent version of my editor, I haven't posted it yet. I want to make two more changes first. In the program you probably noticed that True Type fonts are not shown. All others work, so until I resolve that issue, I choose to disallow them. I haven't had time to do so yet, but Donkey really already pointed us in the right direction when he said to save and restore the entire structure. Because filling out those structures is what the ChooseFont dialog does, he must be correct because it works correctly after this is done. So why don't you write a procedure to save the contents of the CHOOSEFONT, LOGFONT and CHARFORMAT structures. Take the contents of that file and use it to initialize the 3 structures when you create the font at the start of the program and I bet it will work! I am going to do that once my flu goes away.
Paul
Robert Collins,
Your comments in the post:
http://www.masmforum.com/simple/index.php?topic=180.msg1630#msg1630
don't make sense to me. The code in RTFPrint shows very little resemblence to what I have just seen in pbrennick's GENESYS.ZIP project. The only similarities are the standard windows message handling routines. Nothing was used from pbrennick's code to construct RTFPrint. The only things that are "original" in RTFPrint are the routines I highlighted in my post with the attachment. Again, sorry for any confusion. I acknowledged the techniques and code I adapted from Chib777's Print/Preview code. Without that code, I would still be in the dark.
pbrennick,
Your response:
http://www.masmforum.com/simple/index.php?topic=180.msg1663#msg1663
seemed to me to be either defensive or accusatory, I'm not sure which. After looking at your GENESYS.ZIP code--thanks for sharing--I can only assume Robert Collins is confused. I don't think you stole from me--you're futher up the editor/print ladder than I am and you don't need to steal or borrow from me. And I never saw your code before writing mine. Hope I'm overestimating you intentions!
I've studied your code enough to know I will study it more. It covers a lot more than I need right now, but may help me with some future projects.
I did steal from donkey! I used the code he shared with us a while ago which loads the appropriate version of Winspool .drv or .dll Depending on the version of Windows being used. Thanks donkey!
If anyone has a question or comment concerning my RTFPrint program, I will be glad to help or learn!
farrier
farrier,
I am not accusing anybody of anything. My code is free for all to use. If you used any code from one of my projects, it would not be theft because I give it to the community for free. I wish Robert had never accidentally said those words. Okay, the distasteful stuff is done, let's move on.
I appreciate your compliments on my code. I have been coding for many years and even though the move to windows was a huge step (backwards?) for me, I have been able to bring my methods into that platform, as well. It is important to take the time to document your code. If you have any questions about my code or need to tweak a part of it to suit your needs, I will help.
BTW: my editor is the biggest example of a dialog box you will probably ever see. Did you notice that? I thought, for sure, that someone would say something about that!
Paul
One last thought, I have looked at code from others, it is a good way to improve my skills. But I continually run into people writing VERY involved procedures with hundreds of lines to achieve wordwrap fumctionality. They destroy windows and recreate them, etc.
My WordWrap function is 5 lines, 4 of them are only used to do the flip flop. This one has always baffled me.
Paul
Guys,
Lets face it, there is a lot of common code around and when someone is trying to answr a question, its not a copyright debate but an attempt to help someone understand what the code does or what its used for.
pbrennick,
Thanks for your reply. I was confused by the nature of the two replies back to back. What little I've done in windows programming, I've done in MASM32 and FASM and have shared everything openly and without condition. And occasionally I've been able to help others, usually based on the work I've done on my projects. I understand and appreciate your contributions. And I apologize if I misunderstood your intentions and the spirit of your reply.
hutch--,
I agree! My problem was the nature of Robert Collins' "the exactness of both projects" comment. Still doen't make sense.
Imitation is the sincerest form of flaterry. I've flattered many, but not stolen and taken credit for it.
Thanks to al,l for your help :U
farrier
Quote from: farrierI did steal from donkey! I used the code he shared with us a while ago which loads the appropriate version of Winspool .drv or .dll Depending on the version of Windows being used. Thanks donkey!
No problem with that and you're very welcome to "steal" my demo stuff as often as you like :U That is after all the reason I post it.
I should note that we all use a snippet here and there that we find interesting and in some modified form it finds it's way into our "base code'. That is the norm for people like us who freely exchange ideas and code in order to enhance the community and improve our skills. A side effect of this is that we may find that two independant peices of code are very similar in style or even naming conventions, this is something to be proud of, it means that alot of our hard work in disseminating this information is not going to waste. Rather it is building a useful code library that we can all use, improve on and contribute to. It makes me proud to see a little bit of my code in the source of others, it means that I have given a little back to the community has given me so much.
Guys,
Can we leave this crap behind, this is a technical help forum, not a copyright protection or tracing agency. There are two things here, the design for printing code originates from Microsoft who publish the API calls so its not a simple matter of someone creating it and other copying it, its a matter of using the SAME reference material to do the same task so it does end up similar very often.
The other is of course that when someone contributes a good working piece of code, many will use it and thats why it IS contributed in the first place. If it was secret copyright code, it would not have been published in the first place.
The general drift is if you have something useful and you want to share it around, feel free to do so as it helps many other people.
Attached is an update version, showing changes of fonts and sizes of type. Again, this is not a editor, and no changes are supported in the RichEdit control. Just a demo of how to construct an RTF file and how to print it withour user intervention.
To see what is done, open the masm32rtf.rtf file in NotePad and the RTF code is displayed.
farrier
[attachment deleted by admin]