Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Create 2nd console window for debug data

Status
Not open for further replies.

jbs

Programmer
Feb 19, 2000
121
US
I've got an application that I'm building that needs to be debug'ed. Given the data, application, and other factors I think it would be best/easiest to setup a separate console windows that I can send debug text info to while the program is running.

Within the Microsoft Visual Studio.NET development environment, what is the best/straight-forward way to create a secondary command window and send text msgs to it?

thanks/jbs
 
Dont know about .Net, but in MFC there was TRACE() for that purpose.
 
My fault...should have said it upfront. Primary application is a non-managed C++ console application (no MFC included). I'd just like to open up a 2nd console for debuging....and route debugging messages to it....

thanks./jbs
 
Perhaps no way in one application. Implement one of possible inter-process communication techniques, for example:
1. Through a file - main application outputs messages to a file, each time flushing the buffer. Second application monitors new messages incomming to the end of that file.
2. Through a TCP/IP socket.
3. ...
 
you could also create a dll contaning a self-contained debug window on a separate thread, and send messages to the window to add debug text. Easy to do, except you either must hardcode the createwindow/createdialog call in the secondary thread or (as i do) the class that handles this mess has methods that do createwindow(), createdialog(), createdialogindirect(), et cetera; each one packages up the appropriate parameters and then posts a message to the secondary THREAD (not window - there is no window at this point), passing the parameter block as the LPARAM. The secondary thread creates the window and puts the hWnd inside the parameter block where the caller is free to pick it up. (I use an event - also stored in the parameter block - to signal that the hWnd is valid; i also store the GetLastError() if the create*() fails).

Some miscellaneous example snippets used in this solution:
(Note that TryPostThreadMessage() simply tries for a bit to post the message and gives up if it can't after a reasonable amount of time. see ms's PostThreadMessage() docs for the rationale for this, and other methods of dealing with it). the MARSHAL macro copies a user-supplied parameter into the parameter block. Start() starts the secondary thread.
I have omitted some error checking here.


Code:
HWND hdWindowThread::CreatWindow(
		LPCTSTR lpClassName, 
		LPCTSTR lpWindowName, 
		DWORD dwStyle, 
		int x, int y, 
		int nWidth, int nHeight, 
		HWND hWndParent,HMENU hMenu, 
		HINSTANCE hInstance, LPVOID lpParam) {

	Start();

	Shared_CW &Shared=*new Shared_CW;
	MARSHAL(LPCTSTR, lpClassName)
	MARSHAL(LPCTSTR , lpWindowName)
	MARSHAL(DWORD, dwStyle)
	MARSHAL(int, x)
	MARSHAL(int, y)
	MARSHAL(int, nWidth)
	MARSHAL(int, nHeight)
	MARSHAL(HWND, hWndParent)
	MARSHAL(HMENU, hMenu)
	MARSHAL(HANDLE, hInstance)
	MARSHAL(LPVOID, lpParam)
	Shared.hdr.hEvent=CreateEvent(0,1,0,0);
	Shared.hdr.hWnd=0;

	if (!TryPostThreadMessage(idThread,wm_CreateWindow,0,(LPARAM)&Shared)) {
		SetLastError(ERROR_TIMEOUT);
		return (HWND)INVALID_HANDLE_VALUE;
		}

	WaitForSingleObject(Shared.hdr.hEvent,INFINITE);

	CloseHandle(Shared.hdr.hEvent);

	HWND result=Shared.hdr.hWnd;
	if (result==INVALID_HANDLE_VALUE) SetLastError(Shared.hdr.CW_Result);
	delete &Shared;
	return result;
	}

the secondary thread function starts out like:
	while (GetMessage(&msg,(HWND)NULL,0,0)) {
		if (!msg.hwnd) {
			switch (msg.message) {


				case wm_CreateWindow: {
					Shared_CW &Shared=*(Shared_CW*)lpData;
					Shared.hdr.hWnd=::CreateWindow(Shared.lpClassName,
						Shared.lpWindowName,
						Shared.dwStyle,
						Shared.x, Shared.y,
						Shared.nWidth,Shared.nHeight,
						Shared.hWndParent,Shared.hMenu,
						Shared.hInstance,Shared.lpParam);
					if (Shared.hdr.hWnd==INVALID_HANDLE_VALUE) {
						Shared.hdr.CW_Result=GetLastError();
						}
					SetEvent(Shared.hdr.hEvent);
					}
					break;

and then goes on to handle the various other supported Create*() calls. If the message isn't a thread message, the code falls into the normal things you do in a message loop.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top