Hi.

When I create simple "STATIC" window with text content, the font of the text is "System" - big and ugly font. So, the question:

What is easyest way to change the font of the window?
Is this possible to make child windows to take the font of the parent window?

Now I make following:

1. Create control.
2. Create font
3. Send to control WM_SETFONT message with font handle as parameter.

And second question: Must I delete this fonts (with DeleteObject) on the program exit, or Windows will make this for me?
Posted on 2003-07-17 09:31:25 by JohnFound

1. Create control.
2. Create font
3. Send to control WM_SETFONT message with font handle as parameter.
correct.

And second question: Must I delete this fonts (with DeleteObject) on the program exit, or Windows will make this for me?
I can't be sure but it's best to delete the handle yourself. From what I've heard windows will free the resources/handles... but I don't have definitive proof to prove that. I don't have access to BoundsChecker(Numega) or any "reliable" memory leak tracer, but if you have one try running your program against that.
Posted on 2003-07-17 09:43:43 by arkane
Hi Arkane.

I know that my method is right, it simply works, but I ask for some easyest method. For example to set the font for parent window and to "say" to child controls to get font from parent.

And I ask for this because I need to create 40..50 controls, and above sequence of invokes is prety annoying for such big quantity of controls.

Regards.
Posted on 2003-07-17 10:07:57 by JohnFound
.DATA?


FONTDATA STRUCT
hFont DD ?
boolRedraw DD ?
FONTDATA ENDS

fd FONTDATA <>

...

.CODE

...

SetChildFont PROC hWnd:DWORD, lpData:DWORD

mov eax, lpData
mov ecx, (FONTDATA PTR [eax]).hFont
mov eax, (FONTDATA PTR [eax]).boolRedraw
invoke SendMessage, hWnd, WM_SETFONT, ecx, eax
xor eax, eax
inc eax
ret

SetChildFont ENDP

...

WM_CREATE:

;create controls, - edit boxes, buttons....

...

invoke CreateFont, -1, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, \
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \
FF_DONTCARE, OFFSET fFontName

mov fd.hFont, eax
mov fd.boolRedraw, TRUE
invoke EnumChildWindows, hWnd, OFFSET SetChildFont, OFFSET fd
:grin:
Posted on 2003-07-17 10:28:23 by arkane
You don't have to create the Font 50 times... Or delete the Font 50 times... The handle is valid as long as the App Runs (or you destroy the handle)

So all you need is a :


invoke CreateButton
mov handleButton1,eax
invoke Sendmessage,eax,WM_SETFONT,hFont,0


Or you store all your ButtonHandles in an array and loop thru them 1 by 1 after you created all your Buttons... Like:



Array: dd 51 dup(0) ; 1 extra for security

push ebx
xor ebx,ebx
@@:
lea eax,Array+ebx
or eax,eax
jz @F
invoke SendMessage,eax,WM_SETFONT,hFont,0
inc ebx
jmp @B
@@:



I hope you get the general idea

Cheers,
JC
Posted on 2003-07-17 10:31:57 by JimmyClif
Nice idea, arkane :)
Posted on 2003-07-17 10:35:35 by JimmyClif
Your much better off to use CreateFontIndirect, that way if you are using multiple fonts you have only to change a few fields (usually just the typeface and size) and pass the structure. Yes, you have to delete font objects on exit from your program. An alternative way to use a font is to select it into the DC when drawing text but that is only if you draw your text "manually". Make sure that you convert the point size to logical font units using the following formula:
mov eax,96

mul FSIZE
mov ecx,72
div ecx
neg eax
This uses 96 dpi (screen LOGPIXELSY) to calculate the font size for different devices obtain the number with invoke GetDeviceCaps,hDC,LOGPIXELSY.

storing button handles in an array is a good way to do it, you could also use a EnumChildWindows proc to do it.
Posted on 2003-07-17 11:15:16 by donkey
Eureca!!! (Or maybe evrika!!!) :grin:

The final working-out - parent window, automatically setting the font of his child controls. The child controls are created simply with CreateWindow or any other method. Only, don't set WS_EX_NOPARENTNOTIFY for created controls:



; Window class for parent window must be registered with WC.cbWndExtra >= 8
; I am using index 0 for my goals... and index 4 for window font handle.

; This is only the part of the winproc of the parent window:
cmp [wmsg], WM_CREATE
je .create

cmp [wmsg], WM_DESTROY
je .destroy

cmp [wmsg], WM_SETFONT
je .setfont

cmp [wmsg], WM_GETFONT
je .getfont

cmp [wmsg], WM_PARENTNOTIFY
je .parentnotify

.default:
invoke DefWindowProc, [hwnd],[wmsg],[wparam],[lparam]
jmp .finish

;---------WM_PARENTNOTIFY--------------------------
.parentnotify:

movzx eax, word [wparam]
cmp eax, WM_CREATE
jne .default

invoke GetWindowLong, [hwnd], 4
invoke SendMessage, [lparam], WM_SETFONT, eax, TRUE
jmp .finish

;---------WM_SETFONT-------------------------------
.setfont:
invoke SetWindowLong, [hwnd], 4, [wparam]
cmp [lparam], FALSE
je .finish
invoke InvalidateRect, [hwnd], NULL, TRUE
jmp .finish

;---------WM_GETFONT-------------------------------
.getfont:
invoke GetWindowLong, [hwnd], 4
jmp .finish

;---------WM_CREATE--------------------------------
.create:
invoke CreateFont, cBoxFontSize, 0, 0, 0, cBoxFontWeight, \
cBoxFontItalic, FALSE, FALSE, ANSI_CHARSET, \
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_DONTCARE, cBoxFont
invoke SetWindowLong, [hwnd], 4, eax
jmp .qfalse

;---------WM_DESTROY-------------------------------
.destroy:
invoke GetWindowLong, [hwnd], 4
invoke DeleteObject, eax
jmp .dialogproc


.qfalse:
xor eax,eax

.finish:
pop esi ebx edi
return



Maybe a little bit complex, but when you need to create dynamicaly scores of controls, this may be an usefull.

Regards, and thank you for the help.
Posted on 2003-07-17 13:07:34 by JohnFound