Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C
I want to know how to show special characters in an Edit Control in a native Win32 aplication build in C++.
 
I use :
- an Edit Control,
- Courier New as font over this control
- The function SendMessage with the WM_SETTEXT message.
- Win XP SP3 and VS 2010.
 
I want to display a binary file, the problem is it only shows a black square for every character < 32, but when I type ALT-16 on the Edit Control (for example) it shows the ► (this is what I want), so the font is right because it displays the characters < 32 when you type them, but the SendMessage doesnt let me display correctly these characteres.
 
If you could help I appreciate it.
ThanX.
Posted 6-Sep-12 9:21am
Edited 6-Sep-12 12:57pm
v2
Comments
Sergey Alexandrovich Kryukov at 6-Sep-12 15:56pm
   
It depends on how would you want to present such characters. When you decide on it, why anything could be a problem?
--SA
fvalerin at 6-Sep-12 18:02pm
   
I want to present them like the old DOS system (that's what for example Notepad does when type ALT-2 an icon with a smiling face appears), a heart for ascii 3, etc, etc.
The problem is what I explained in the question
pasztorpisti at 6-Sep-12 19:34pm
   
My solution was indeed broken on WinXP, this time I came up with a new solution on my WinXP SP2. Check it out!
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

The thing about using the alt-codes is that they generate non-ascii characters. Using SetWindowText or WM_SETTEXT directly deal with ascii characters.
 
Furthermore, alt-248 does not correspond to ascii char 248 (alt-248 = ascii 176 = degrees symbol - °)
 
You can see that the codes presented here: http://www.alt-codes.net/[^]
are different to those shown here: http://www.ascii-code.com/[^]
 
If I use the following character string:
char mStr[] = {'a','b', 149, '°', 176, 230, 0};
Then I get this shown (which is the expected output)
ab•°°æ
  Permalink  
v4
Comments
fvalerin at 6-Sep-12 15:54pm
   
I dont understand your solution, I mean having the characters in the string mStr it is not displaying the characters and is logic. Of course I have the characters in a string, that's why I said I use the SendMessage function.
 
The Alt-16 like I said was an example to demonstrate the FONT shows correctly these characters. What I lack is the right method to display.
 
Please, people I urge you on to not divert the subject of the question over the ALT thing.
 
Thank you anyway.
enhzflep at 6-Sep-12 16:02pm
   
The point is that Alt-16 some alt-codes generate the character code for a character that can only be described with unicode.
The other point was that you already have the ability to send all ascii chars - but you must make sure you're sending the correct _ascii_ code for each char.
 
As I said earlier, Alt-248 = °. The ascii code for this char is 176. Therefore we need to send 176, _not_ 248 to the edit control in order to display the °.
 
The question is intrinsically linked to the concept of the two different character sets. Without understanding the difference, one is bound to use one convention with the other system and wonder why the 'correct' characters aren't displayed.
fvalerin at 6-Sep-12 18:10pm
   
The thing is to display the characters in a text box (edit control) with his associated icon like the old "type" instruction in a command prompt does, when you type "C:\type somefile.exe" you will get a smiling face for the binary value 2, a heart for the binary value 3, a ► for the binary value 16.
 
In this system the binary value 176 is ░ and the binary value 248 is ° (what you call ALT codes).
 
It doesn matter the name, just let me know how to do it.
enhzflep at 6-Sep-12 18:38pm
   
Yes, yes and yes. I've been tapping them out for over 20 years. I'm well aware of the concept. For your own sake - look up the ascii code of the char you'd like to display and then send it. If you can't find a table, then make a tool that will show you the char value of any char in the edit box.
I just did that for the ► character. It's char-code is 9658
 
So, if you've got unicode turned on, then a string defined thusly:
wchar_t mStr[] = {9658,0,0};
Will display a single ► when sent to a window
 
Here's a snippet from a dialog's initialization - it shows the right-pointing arrow.
 

 

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HWND editWnd;
wchar_t mStr[] = {9658,0,0};
switch(uMsg)
{
case WM_INITDIALOG:
editWnd = GetDlgItem(hwndDlg, IDC_EDIT1);
SetWindowText(editWnd, mStr);
return TRUE;
 
EDIT:
 
Here's some code for getting the char-codes:
 
wchar_t mStr2[1024], mStr3[1024]={}, curNum[16];
int i;
case IDC_BTN_TEST:
GetWindowText(editWnd, mStr2, 1024);
for (i=0; i<wcslen(mStr2); i++)
{
wsprintf(curNum, L"%d, ", (unsigned int)mStr2[i]);
 
wcscat(mStr3, curNum);
}
MessageBox(hwndDlg, mStr3, L"Information", MB_ICONINFORMATION);
return TRUE;
fvalerin at 7-Sep-12 15:01pm
   
Boths solutions work (the one for pasztorpisti and the one for enhzflep)
 
Conclusions for others searching about this topic :
 
In both cases we are asumming that you must create a font with CreateFontW an assign it to the Edit Control.
 
In this solution 2, for XP SP3 : several fonts work, I use "Courier New".
 
You must search (at design time) for the right char-code for every character you want to display, then take note, build a table to map between the binary value of the character and the char-code, and then assign the char-code to the string variable that you will use to display (using SendMessage in this case).
 
Thank you for your time and help.
enhzflep at 7-Sep-12 15:11pm
   
You're most welcome, extra 'points' for coming back to the question and adding a conclusion for all those that follow. :)
 
I'd be inclined to download the source-code for an open-source hex-editor for an alternative approach to the problem - surely it's been tackled innumerable times already. My approach could never be claimed as a generic approach for all (generally) non-printable characters - though my aim was to show the lack of a direct correlation between character-codes and so-called alt-codes.
S. :)
fvalerin at 7-Sep-12 16:10pm
   
Thanx again, another good idea, I'll try to do that, i dont know when yet, to search for the open source code of a tool like that.
 
I gave you points too, now. (Im not used to use forums).
enhzflep at 7-Sep-12 20:35pm
   
:D
 
Expanding on what pasztorpisti said earlier - the character set shown by the VGA card on (western, english-speaking) PCs is also referred to as Code Page 437. Although not designed as a code-page (merely as 256 glyphs), it has become known colloquially as one.
 
A number of years ago, Microsoft released a TTF font that was specifically designed to replicate the characters in the 256 char set accurately - It's called MS Line Draw - Version 2.0 (You can get it here: Microsoft: MS Line Draw font
There's also some interesting background information on the Code_page_437 page at Wikipedia. Here: CodePage 437
Enjoy!
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Just tried and the code below works fine for me with any combination. Note that you might want to set the font for your edit control to some monospaced type.
#include "stdafx.h"

#include <windows.h>
HINSTANCE g_hInstance = (HINSTANCE)GetModuleHandle(NULL);
HWND g_hMainWnd = NULL;
bool g_MovingMainWnd = false;
POINT g_OrigCursorPos;
POINT g_OrigWndPos;
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HFONT font = CreateFontW(
		25, 0, 0, 0,
		FW_DONTCARE,
		FALSE,
		FALSE,
		FALSE,
		DEFAULT_CHARSET,
		OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,
		DEFAULT_PITCH,
		L"Terminal");
 
	switch (uMsg)
	{
	case WM_CREATE:
		if (HWND hEdit = ::CreateWindowExW(0, L"Edit", L"", WS_CHILD|WS_VISIBLE|WS_BORDER, 0, 0, 150, 50, hWnd, (HMENU)1, g_hInstance, NULL))
		{
			SendMessageW(hEdit, WM_SETFONT, (WPARAM)font, 0);
			SendMessageW(hEdit, WM_SETTEXT, 0, (LPARAM)L"\x07\x08\x10\x11_XYZ");
		}
		break;
	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			if (HDC dc = BeginPaint(hWnd, &ps))
			{
				printf("%p\n", font);
				HGDIOBJ orig_font = SelectObject(dc, font);
				RECT rt;
				GetClientRect(hWnd, &rt);
				rt.top += 60;
				static const wchar_t TXT[] = L"\x04\x0b\x11_XYZ";
				DrawTextW(dc, TXT, wcslen(TXT), &rt, DT_LEFT|DT_TOP|DT_NOPREFIX|DT_INTERNAL);
				SelectObject(dc, orig_font);
				EndPaint(hWnd, &ps);
			}
		}
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
bool CreateMainWnd()
{
	static const wchar_t CLASS_NAME[] = L"MainWndClass";
	WNDCLASSW wc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hInstance = g_hInstance;
	wc.lpfnWndProc = &MainWndProc;
	wc.lpszClassName = CLASS_NAME;
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
	if (!RegisterClassW(&wc))
		return false;
	g_hMainWnd = CreateWindowExW(
		0,
		CLASS_NAME,
		L"Main Window",
		WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
		CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
		NULL,
		NULL,
		g_hInstance,
		NULL
		);
	return true;
}
int main()
{
	if (!CreateMainWnd())
		return -1;
	ShowWindow(g_hMainWnd, SW_SHOW);
	UpdateWindow(g_hMainWnd);
	MSG msg;
	while (GetMessageW(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}
	return (int)msg.wParam;
}
EDIT: Modified the source code. The original code was written on Win7. I tested it on my WinXP SP2 at home and it didn't work for me. My opinion is that it has something to do with the fonts (they don't contain characters below 32) because on my system the only font that worked is the Terminal, but that font has only really crappy low resolution characters. What I recommend is to get a good font that contains every characters, embed it to your program for example as a resource and then load it for your program like this: How to Use a Font Without Installing it[^].
I checked some MS codepages on the internet and they don't contain glyphs for control characters: http://msdn.microsoft.com/en-us/library/cc195060.aspx[^]. Maybe on newer operating systems they patched some of their fonts...
You should search for free IMB 437 DOS codepage or whaterver fonts on the internet. Don't forget to check out the license of the font before embedding it to your app!!!
 
EDIT: I havent check why did the old code work on Win7 but it can have the following reasons:
1. The default font there contained the control characters.
2. DrawText() on Win7 might used character substitution that drew the missing control characters using another font
 
I checked that in a Word processor I can copy paste in special characters with many fonts, but that might be the effect of font substitution. What I recommend is checking out your binary font files with a font editor program. A free multiplatform font editor program is fontforge, it works quite well but its crossplatform gui is a bit awful. Currently I don't have time for this.
  Permalink  
v5
Comments
fvalerin at 6-Sep-12 17:56pm
   
It doesnt work, at least for me.
Did I mention that I am in Win XP SP3 and VS 2010.
I test it with MultiByte character set and Unicode character set (in the project settings) and with several monospaced fonts
fvalerin at 7-Sep-12 14:55pm
   
Boths solutions work (the one for pasztorpisti and the one for enhzflep)
 
Conclusions for others searching about this topic :
 
In both cases we are asumming that you must create a font with CreateFontW an assign it to the Edit Control.
 
In this solution 1, for XP SP3 works only with the font "Terminal" (it remains as homework to search for anothers)
 
Besides you could do both of these :
 
wchar_t cadena[10] = { 1, 2, 3, 4, 5, 0 } ; // option 1 (or)
wchar_t cadena[10] = { '\x1', '\x2', '\x3', '\x4', '\x5', 0 } ; // option 2
 
SendMessageW(hEdit, WM_SETFONT, (WPARAM)font, 0);
SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM) cadena );
 
Thank you for your time and help.
pasztorpisti at 7-Sep-12 18:06pm
   
You're welcome!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 245
1 Jochen Arndt 155
2 PIEBALDconsult 150
3 Afzaal Ahmad Zeeshan 120
4 DamithSL 115
0 OriginalGriff 5,695
1 DamithSL 4,591
2 Maciej Los 4,012
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,190


Advertise | Privacy | Mobile
Web02 | 2.8.141220.1 | Last Updated 6 Sep 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100