outputting text in Windows programs (C++)

Started by
5 comments, last by slippers2k 19 years, 8 months ago
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

	switch(message)
	{
	case WM_CREATE:				// window is being created
		return 0;
		break;

	case WM_CLOSE:				// window is closing
		PostQuitMessage(0);
		return 0;
		break;

	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

		/****************************************************************************
		pseudocode

		if (sizeof(string) > width_of_window)
			break_into_pieces(string);

		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);

		Problems?

		* 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;
		break;

	default:
		break;
	}

	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);
	windowClass.style = 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
					WS_VISIBLE |
					WS_SYSMENU,
					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
		}
		else
		{
			TranslateMessage(&msg);				// translate and dispatch to event queue
			DispatchMessage(&msg);
		}
	}

	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]
Attack life's problems like a Subaru... with all four wheels
Advertisement
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]
.
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
-slippers2k
Attack life's problems like a Subaru... with all four wheels
There's also TextOut which is less fancy but faster than DrawText
Quote: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.
.
Oops! My bad! Sorry. :)
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"
output_next_string;
}

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.)

-slippers2k
Attack life's problems like a Subaru... with all four wheels

This topic is closed to new replies.

Advertisement