[try Beta version]
Not logged in

 
Fonts problem

Apr 26, 2011 at 7:04pm
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;
	 
 }
Apr 26, 2011 at 7:19pm
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 Apr 26, 2011 at 7:20pm
Apr 26, 2011 at 7:29pm
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.

Apr 26, 2011 at 7:33pm
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.
Apr 26, 2011 at 7:45pm
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().
Apr 26, 2011 at 7:47pm
http://msdn.microsoft.com/en-us/library/dd144904(VS.85).aspx

That's for GetObject(). GetCurrentObject() is nearby.
Apr 26, 2011 at 7:51pm
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.
Apr 26, 2011 at 7:58pm
@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 Apr 26, 2011 at 8:00pm
Apr 26, 2011 at 8:09pm
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
Apr 26, 2011 at 8:13pm
@ 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 Apr 26, 2011 at 8:13pm
Apr 26, 2011 at 8:20pm
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 Apr 26, 2011 at 8:21pm
Apr 27, 2011 at 2:18pm
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.
Apr 27, 2011 at 5:45pm
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.
Apr 28, 2011 at 3:12pm
is the edits box's DC the handle to the window or is it the result of BeginPaint(), or is it something else?
Apr 28, 2011 at 4:05pm
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.
Apr 28, 2011 at 7:38pm
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?
Apr 29, 2011 at 2:03am
It is the return value of the SendMessage() function.
Apr 29, 2011 at 2:24pm
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?
Apr 29, 2011 at 3:15pm
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.
Apr 29, 2011 at 5:42pm
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 Apr 30, 2011 at 2:31pm
Topic archived. No new replies allowed.