Click here to Skip to main content
15,868,292 members
Please Sign up or sign in to vote.
3.67/5 (3 votes)
See more:
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
Updated 6-Sep-12 11:57am
v2
Comments
Sergey Alexandrovich Kryukov 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 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 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!

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:
C++
char mStr[] = {'a','b', 149, '°', 176, 230, 0};

Then I get this shown (which is the expected output)
ab•°°æ
 
Share this answer
 
v4
Comments
fvalerin 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 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 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 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 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.
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.
C++
#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.
 
Share this answer
 
v5
Comments
fvalerin 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 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 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)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900