Fonts problem

hello every one.
i am making my one version of notepad.
i am trying to make the option that you can change the font.
the problem is, it wont work. Wen I try to change the font, the font stays the same. it doesn't give any errors, but the font stays the same.
here is a bit my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
HFONT GetFont(int Width,int Height,wstring type,bool italics,bool underline,int boldness)
{
	HFONT hf;
	hf = CreateFont(Height,Width,0,0,boldness,italics,underline,0,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY,VARIABLE_PITCH,type.c_str());
	return hf;

}
int wStoI(wstring source)
{
	wstringstream conv;
	int result;

	conv<<source;
	conv>>result;
	return result;

}


int fontW;
	int fontH;
	wstring font;
	bool italics;
	bool bBold;
	bool line;
	bool Create = true;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int bold;
	HWND hEdit = 0;
	int ID;
	int YESNO;
	wstring text;
	wstring cText;
	HFONT hf;

	switch (message)
	{
	case WM_CREATE:
		if(Create)
		{
		Create = false;

		hEdit = CreateWindow(L"EDIT",0,WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_AUTOHSCROLL |ES_AUTOVSCROLL | WS_BORDER | WS_HSCROLL |WS_VSCROLL  ,50,25,500,500,hWnd,	(HMENU)EDIT,hInst,0);
		}
		if(bChanged){

					if(bBold){bold = FW_BOLD;}
					if(!bBold){bold = FW_DONTCARE;}

				hf = GetFont(fontW,fontH,font,italics,line,bold);
				SendMessage(hEdit,WM_SETFONT,(WPARAM)hf,0);
				SendMessage(hWnd,WM_SETFONT,(WPARAM)hf,0);
				
				}
		break;

	case WM_COMMAND:
		ID = LOWORD(wParam);
		switch(ID)
		{
			case ID_FONT_VERANDER:
				DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),0,ChangeFontCB);
				if(bChanged){

					if(bBold){bold = FW_BOLD;}
					if(!bBold){bold = FW_DONTCARE;}

				hf = GetFont(fontW,fontH,font,italics,line,bold);
				SendMessage(hEdit,WM_SETFONT,(WPARAM)hf,0);
				SendMessage(hWnd,WM_CREATE,(WPARAM)hf,0);
				
				}
				break;


			case ID_FILE_OPEN :
				Open(hWnd);
				break;
			case ID_FILE_SAVE:
				Save(hWnd);
				break;
			case ID_FILE_NEW:
				YESNO = ::MessageBox(hWnd,L"do you want to save first?",L"save?",MB_YESNO);
					switch(YESNO)
				{
					case IDYES:
						Save(hWnd);
						SetDlgItemText(hWnd,EDIT,L"");
						break;
					case IDNO:
						SetDlgItemText(hWnd,EDIT,L"");
						break;


				}
				break;
			case ID_CODEEREN_CODEER:
				YESNO = ::MessageBoxW(hWnd,L"some things go lost in the coding/decoding proces, do you want to continue?\n\ this function should only be used in single sentences.",L"warnig",MB_YESNO);
				switch(YESNO)
				{
				case IDNO:
					break;
				case IDYES:
					text = readTextBox(hWnd,EDIT);
					encode(text,cText);
					SetDlgItemText(hWnd,EDIT,cText.c_str());
					break;

				}
				break;

			case ID_CODEEREN_DECODEER:
					cText = readTextBox(hWnd,EDIT);
					decode(cText,text);
					SetDlgItemText(hWnd,EDIT,text.c_str());
				break;
		}
		break;

	case WM_DESTROY:
	
		PostQuitMessage(0);

		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
BOOL CALLBACK ChangeFontCB(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
	 int ID;
	
	 switch(uMsg)
	 {
	 case WM_INITDIALOG:
		 return true;

	 case WM_COMMAND:
		 ID = LOWORD(wParam);

		 switch(ID)
		 {
		 case IDOK:
			 font = readTextBox(hWnd,IDC_TYPE);
			 fontW = wStoI( readTextBox(hWnd,IDC_WIDTH));
			 fontH= wStoI( readTextBox(hWnd,IDC_HEIGHT));
			 bChanged = true;
			 EndDialog(hWnd,2);
			 return true;
			 break;
		 case IDC_ITALICS:
			 if(italics){italics = false;}
			 if(!italics){italics = true;}
			 break;
		 case IDC_VET:
			 if(bBold){bBold = false;}
			 if(!bBold){bBold = true;}
			 break;
		 case IDC_LINE:
			  if(line){line = false;}
			  if(!line){line = true;}
			  break;

		 }
		 break;


	case WM_CLOSE:
		EndDialog(hWnd,2);
		break;
	default:
		return false;
	}
	return 0;
	 
 }
Which CB function did you register with the window?

Are you clearing and redrawing the screen after changing the font? <- Not %100 sure you would need to but it's something to try.

Have you checked to see if the command worked by using WM_GETFONT? This is necessary since "SendMessage(...)" only passes the return value of the message on to you and "WM_SETFONT" doesn't return anything.
Last edited on
the main window is registerd with WndProc().
the dialog to set the font uses the ChangeFontCB() function.

i tried to clean the screen using system("cls"), and redrawing using InvalidateRect(), with the last argument true and false.

neither of these things worked.

You are also not testing for the success or failure of the font creation. Your code is just assuming that it always succeeds. And remember that even if it succeeds and depending on your choices (arguments), you could still get a different font. Use GetCurrentObject() and GetObject() to verify that the font is in fact the font you want.
i had added the code to test if the handle to the font was zero. the handle was not zero. and the font stays the same. i also tested if the other arguments were good, and they ware good. i don't know how to use GetCurrentObject() and GetObject().
http://msdn.microsoft.com/en-us/library/dd144904(VS.85).aspx

That's for GetObject(). GetCurrentObject() is nearby.
system("cls") would send the string "cls" to the OS through the shell. This string means exactly jack to a Win32 Window so no you are not clearing the screen with it.

InvalidateRect(...) was a good try, but do you have anything to actually redraw your data to the screen?

GetCurrentObject(...): http://msdn.microsoft.com/en-us/library/dd144869(VS.85).aspx

GetObject(...) seems to be a COM function, that's a whole leason on it's own.
@Computergeek01: See the link I provided for GetObject(). It is NOT COM. It is GDI.

Also note that there is an edit box here in charge of being the editable area. I don't think the program needs to do any redrawing on its own to show a font change. That should be the work of the edit window, right?
Last edited on
this is how i edited the GetFont() function:
1
2
3
4
5
6
7
8
9
10
11
12

	LPVOID buf = 0;
	
	HGDIOBJ test = 0;
	HFONT hf = CreateFont(Height,Width,0,0,boldness,italics,underline,0,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY,VARIABLE_PITCH,type.c_str());

	if(hf == 0){MessageBox(0,L"the font is empty",L"",MB_OK);}
	GetObject(hf,100,buf);
	if (buf == 0) {MessageBox(0,L"the font has no bites",L"",MB_OK);}
	 test = GetCurrentObject((HDC)hf,OBJ_FONT);
	 if (test == 0) {MessageBox(0,L"the handle is empty",L"",MB_OK);}
	return hf;


i got two times the message that the font is empty and that the font has no bites. i don't know why they are zero
@ webJose: Ah, so you are correct. The first result from my MSN toolbar was a COM object with the same name that would work but requires initiating COMs. I must have missed your post, I don't always refreash right before I submit.

My comment was based on the thought that you would still need to redraw that area, IDK for sure. I looked up a simpler text editor I did on my own and saw that I was clearing and redrawing it in some cases. I didn't have a way to change the font though. The one I wrote was so long ago that I can't remember, it was also from a point where I was still doing things that didn't need to be done.
Last edited on
You are not using GetObject() correctly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//First find out the number of bytes needed to retrieve the information.
int bufSize = GetObject(hf, 0, NULL);
//Strictly speaking, bufSize could be zero here, meaning the above function call failed.  You should check that in production-grade code.  I am omitting here.
LPVOID buffer = new BYTE[bufSize];
//Now that you have a buffer, you can call GetObject().
int r = GetObject(hf, bufSize, buffer);
if (!r)
{
    MessageBox(NULL, TEXT("The call to GetObject() failed."), TEXT("Error Message"), MB_OK);
}
else
{
    //You can examine the returned data here.
    LOGFONT *pFontInfo = (LOGFONT*)buffer;
    //The font's name for example:
    MessageBox(NULL, pFontInfo->lfFaceName, TEXT("Retrieved Font Name"), MB_OK);
}
//Always free allocated memory in the heap.
delete[] buffer;
Last edited on
the result of the tests are that i get a message witch says the font type, even if the font does not exist, and the font stays the same.
Ok, so the font might be created OK. Verify that WM_SETFONT works as expected by getting the edit box's DC and retrieving the font object with GetCurrentObject(). Then use GetObject() on the retrieved object to see if its properties match the expected properties.
is the edits box's DC the handle to the window or is it the result of BeginPaint(), or is it something else?
It is NOT the window handle, it is the handle obtained by calling GetDC(hEdit), but now that I think of it, the approach would be OK only if edit boxes own the DC. If they don't own the DC, then the font will not be selected in the returned DC and verification won't be possible. And even if the DC is owned, there is no guarantee that the font will be there selected (it sure is the logical thing, though).

So I guess the method I propose with GetCurrentObject() is no good. Is there a WM_GETFONT message? That might be the only truthful way of obtaining the edit box's font.
there is a message WM_GETFONT (http://msdn.microsoft.com/en-us/library/ms632624(v=vs.85).aspx), this might be a stupid question, but how do you get a return form a message?
It is the return value of the SendMessage() function.
the returned handle to the font from the message is not equal to the handle of the font returned by the function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
case ID_FONT_CHANGE:
				DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),0,ChangeFontCB);
				if(bChanged){

					

				hf = GetFont(fontW,fontH,font,italics,line,bold);
				SendMessage(hEdit,WM_SETFONT,(WPARAM)hf,0);
				hfTest = (HFONT)SendMessage(hWnd,WM_GETFONT,0,0);
				
				if ( hf != hfTest) { MessageBox(hWnd,L"the font does not match the test font",L"error", MB_OK);}

				}
				break;


so how come the fonts don't match, and is this why the font is bad?
According to http://msdn.microsoft.com/en-us/library/ms632642(VS.85).aspx, you should pass TRUE in the LPARAM when sending WM_SETFONT to make the control redraw itself.

But that is just a note. What I suggest:

Try to draw on your main form using the created font. See if it works OK. This should prove that the created font has no problems.

As for the EDIT box, obtain the font before WM_SETFONT, and then obtain the font after WM_SETFONT. Compare the handles. Do they change? Another test: Use GetObject() on the fonts obtained via WM_GETFONT to see what font it is.
wen i try to change the font of the main window, it does not change, and before and after the WM_SETFONT message hfTest stays 0. so I think that the problem lays in the creation of the font.
So what is wrong whit :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
HFONT GetFont(int Width,int Height,wstring type,bool italics,bool underline,int boldness)
{
	HFONT hf;
	hf = CreateFont(Height,Width,0,0,boldness,italics,underline,0,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY,VARIABLE_PITCH,type.c_str());


int bufSize = GetObject(hf, 0, NULL);
//Strictly speaking, bufSize could be zero here, meaning the above function call failed.  You should check that in production-grade code.  I am omitting here.
LPVOID buffer = new BYTE[bufSize];
//Now that you have a buffer, you can call GetObject().
int r = GetObject(hf, bufSize, buffer);
if (!r)
{
    MessageBox(NULL, TEXT("The call to GetObject() failed."), TEXT("Error Message"), MB_OK);
}
else
{
    //You can examine the returned data here.
    LOGFONT *pFontInfo = (LOGFONT*)buffer;
    //The font's name for example:
    MessageBox(NULL, pFontInfo->lfFaceName, TEXT("Retrieved Font Name"), MB_OK);
}
//Always free allocated memory in the heap.
delete[] buffer;
return hf;
}

Last edited on
Topic archived. No new replies allowed.