Sign in to follow this  

outputting text in Windows programs (C++)

Recommended Posts

slippers2k    138
Hello everyone... Trying to write a C++ program for Windows... basically it's just a tester to see what output text looks like. I succeeded in copying a book's example that outputs a small string to the screen. Here's my dilemma. I'm trying to write a function that will wrap text in a window. Here's my code so far:
#define WIN32_LEAN_AND_MEAN		// trim the excess fat from Windows

#include <windows.h>			// the standard Windows app include

// the Windows Procedure event handler
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
	PAINTSTRUCT paintStruct;
	HDC hDC;					// device context
	char string[] = "Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!";	// text to be displayed

	case WM_CREATE:				// window is being created
		return 0;

	case WM_CLOSE:				// window is closing
		return 0;

	case WM_PAINT:				// window needs updating
		hDC = BeginPaint(hwnd, &paintStruct);

		// set text color to blue
		SetTextColor(hDC, COLORREF(0x00FF0000));

		// display text in middle of window


		if (sizeof(string) > width_of_window)

		break_into_pieces will be a recursive function, splitting the string up
		into portions small enough to be displayed on one line.

		Base case:										Iterative Steps:
		if (sizeof(string) <= calculated_ok_length)		break_into_pieces(string1);
			TextOut(...);								break_into_pieces(string2);


		* Still not automatically checking to see if we are splitting words
			- need a way of checking words
		TextOut(hDC, 0, 100, string, sizeof(string)-1);

		EndPaint(hwnd, &paintStruct);
		return 0;


	return (DefWindowProc(hwnd, message, wParam, lParam));

// The application entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
	WNDCLASSEX	windowClass;		// window class
	HWND		hwnd;				// window handle
	MSG			msg;				// message
	bool		done;				// flag saying when your app is complete

	// fill out the window class structure
	windowClass.cbSize = sizeof(WNDCLASSEX); = CS_HREDRAW | CS_VREDRAW;
	windowClass.lpfnWndProc = WndProc;
	windowClass.cbClsExtra = 0;
	windowClass.cbWndExtra = 0;
	windowClass.hInstance = hInstance;
	windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	windowClass.lpszMenuName = NULL;
	windowClass.lpszClassName = "MyClass";
	windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

	// register the window class
	if (!RegisterClassEx(&windowClass))
		return 0;

	// class registered, so now create your window
	hwnd = CreateWindowEx(NULL,						// extended style
					"MyClass",						// class name
					"A REAL Windows Application!",	// app name
					WS_OVERLAPPEDWINDOW |			// window style
					100, 100,						// x,y coordinate
					300, 300,						// width, height
					NULL,							// handle to parent
					NULL,							// handle to menu
					hInstance,						// application instance
					NULL);							// no extra params

	// check if window creation failed (hwnd would equal NULL)
	if (!hwnd)
		return 0;

	done = false;		// initialize the loop condition variable

	// main message loop
	while (!done)
		PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);

		if (msg.message == WM_QUIT)				// do you receive a WM_QUIT message?
			done = true;						// if so, time to quit the application
			TranslateMessage(&msg);				// translate and dispatch to event queue

	return msg.wParam;

Note the pseudocode... am I any closer to a solution? :) The code above is a simple text output program. I purposely made the string output waaaay too big to fit on one simple output to see if it would wrap automatically. It didn't. I already have the basic idea/algorithm for word wrap: * if(sizeof(next_word) > x_space_left_in_window) go_to_next_line; //usually endl in c++ I just need to know the commands to make it happen. Thanks for your help. I am quite open to criticism, please do remember though, this is just a sample prog, and I do intend to be waaaay more thorough with my real programs. -slippers2k [Edited by - slippers2k on August 3, 2004 11:17:16 PM]

Share this post

Link to post
Share on other sites
Mastaba    761
Use DrawText or DrawTextExt to automatically handle text wrapping. You simply pass it some flags, the text, and a rectangle to draw in. You can configure it so that the command will automatically modify the rect's height if the string is wider than the initial rect.

[Edited by - Mastaba on August 3, 2004 11:06:12 PM]

Share this post

Link to post
Share on other sites
slippers2k    138
Thank you!

DrawText did it. I did have to go on the MSDN website to figure out how it worked, but it wasn't so hard once I understood it.

Appreciate the assist. This is one step closer to understanding word wrap for a bigger project I'm working on.

God bless you

Share this post

Link to post
Share on other sites
Mastaba    761
Original post by chadmv
There's also TextOut which is less fancy but faster than DrawText

If you read the original code posted, he was originally using TextOut. But his question, in the beginner's forum, was about word wrapping. TextOut is faster because it doesn't do any text formating, e.g. word wrapping. You could implement the word wrapping manually, but that would be a bit more than a beginner would probably want to deal with, as you'd have to split your string up into discrete parts (words, white spaces, line breaks, etc.) and see how long each one is before you draw them, so you can calculate the proper formating and then draw them with TextOut in the correct position.

Share this post

Link to post
Share on other sites
slippers2k    138
chadmv: Thanks for the suggestion. I had thought about ways to output using TextOut before.

Mastaba: Thanks for the clarification. chadmv's suggestion actually leads me to my next point.

I was trying to use "intelligent" word handling with TextOut before, so that I could figure out how to manually word wrap with it. I got as far as a potential if statement like I previously stated before...

if (sizeof(string) > amount_of_room_left)
goto_next_line; // set x coord to 0, y down next "unit"

The above approach might work if the string is just "fed" to the screen units at a time. However, I do not believe this is the case. Just like you mentioned, it sounds like I need to figure out how much room my strings are going to have in advance.

I already have the basic idea down (and ultimately, the use of this homegrown word-wrap algorithm won't be for a display in Windows per se, but a full screen game). The calculations for how big the string needs to be each line will basically be dependent upon the resolution of the screen and how big my text box is for displaying information.

My text box will basically have four lines of text. An enormously large string could basically be broken up into four string increments as it is output to the screen:

* if I know how many pixels or text positions I have, I know how long the next piece of string will be that I need to "cut off" and display on screen for each line.

The display would need to pause so the reader can read each box worth of text. Then the box would be cleared and output would be fed in again. (Think about Final Fantasy text screens and you'll get the idea.)


Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this