Learning programming started from Dos. after a certain period of time of tc2.0, it became a bad habit of using printf to output variable values for debugging. When I got to write the window program, I encountered some trouble.
The window program does not have a convenient method for console output (I don't Know), so it is too troublesome to use MessageBox for output debugging for several years, messageBox will interrupt the program process and manually let it continue running, which is the most annoying.
Later, I used VC. net2003 and found that there is an outputdebugstring debugging API. When debugging in IDE, it will direct its output to the debugger in IDE.
Later, we found debugtrack, which can intercept output of outputdebugstring, rather than using other bulky debugger.
As a result, according to its reference documents, I wrote a program llyf debugcapture that intercepts outputdebugstring output.
Debugcapture follow this document (http://www.unixwiz.net/techtips/outputdebugstring.html
) To capture the debugging output:
First, create a new thread to loop in the thread:
Void _ fastcall tcapturedbstring: Execute ()
{
/*************************************** **************************************** *************
* 1. Create the shared memory segment and the two events. If we can't, exit.
* 2. Set the dbwin_buffer_ready event so the applications know that the buffer is available.
* 3. Wait for the dbwin_data_ready event to be signaled.
* 4. Extract the process id nul-terminated string from the memory buffer.
* 5. Go to step #2
**************************************** **************************************** ************/
Tsharedmem Sm ("dbwin_buffer", sizeof (struct dbwin_buffer ));
Tlistitem * item;
Char szfilename [max_path];
Hbufreadyevent = createevent (
Null, // No security attributes
False, // auto-Reset event
False, // initial state is nonsignaled
"Dbwin_buffer_ready" // Object Name
);
If (hbufreadyevent = NULL)
{
MessageBox (getactivewindow (),
"Cannot create event of dbwin_buffer_ready ",
Null,
Mb_ OK );
Return;
}
Hdatareadyevent = createevent (
Null, // No security attributes
False, // auto-Reset event
False, // initial state is nonsignaled
"Dbwin_data_ready" // Object Name
);
If (hbufreadyevent = NULL)
{
MessageBox (getactivewindow (),
"Cannot create event of dbwin_data_ready ",
Null,
Mb_ OK );
Return;
}
While (1)
{
: Setevent (hbufreadyevent );
: Waitforsingleobject (hdatareadyevent, infinite );
If (terminated) // thread terminated flag
{
: Setevent (hbufreadyevent );
Closehandle (hbufreadyevent );
Closehandle (hdatareadyevent );
Return;
}
Debugstring = * (struct dbwin_buffer *) (Sm. buffer ()));
Entercriticalsection (& criticalsection );
// Display the result string
// Including PID, output string, process path
Item = mainform-> debuglistview-> items-> Add ();
Item-> caption = inttostr (mainform-> debuglistview-> items-> count );
Item-> subitems-> Add (inttostr (debugstring. dwprocessid ));
Item-> subitems-> Add (debugstring. data );
Item-> subitems-> Add (getprocesspath (debugstring. dwprocessid, szfilename ));
Listview_ensurevisible (mainform-> debuglistview-> handle, mainform-> debuglistview-> items-> count-1, false );
Leavecriticalsection (& criticalsection );
}
}
The structure used for memory ing for data transmission is as follows:
Struct dbwin_buffer {
DWORD dwprocessid;
Char data [4096-sizeof (DWORD)];
};
In this way, I do not need to use other Debugger for debugging like DOS.
To be more like printf, you can add a wrapper to outputdebugstring:
# Include <stdio. h>
# Include <stdarg. h>
/*************************************** **********
* Example usage (just like C library function ** printf **):
*......
* Outputdebuuplintf ("error: % d.", getlasterror ());
*......
**************************************** *********/
Void outputdebuuplintf (lpctstr ptzformat ,...)
{
Va_list vlargs;
Tchar tztext [1024];
Va_start (vlargs, ptzformat );
Wvsprintf (tztext, ptzformat, vlargs );
Outputdebugstring (tztext );
Va_end (vlargs );
}
You can call outputdebugprs INTF to format the output like printf, haha.