Clue  


About
Clue Monitoring
Programming For Clue
Special Thanks
Miscellaneous
History of Clue
Appendix A

About


Programmed by: Jeff Braun
Version: 2.0.0 (Intel x86, BeOS R5.0.3) Development
Contact: yobkadon@hotmail.com
Web: http://brauns.dyndns.org
Date: September 30th, 2002


THIS DOCUMENTATION HAS NOT BEEN UPDATED FOR THE 2.0.0 RELEASE

ATTN: this is a Development release of Clue. The program and this documentation are unfinished at this time. If you need a stable version, use 2001.5.16.

Clue comes in 6 languages, Swedish and Spanish are coming:

However, at this time, only the Clue application is translated, the documentation is not.

Introduction



Clue2.gif

Clue is my attempt at a GUI printf for debugging purposes. I was tired of just having to printf to a Terminal session all the time, which can get very messy. I didn't really see much else out there for doing GUI debug messages that I liked, so I decided to write my own. There are just a couple of macros you need to include in your file to allow easy multi-threaded debugging. The "Monitor" portion of everything is the Clue app, while the "Programming" portion of things is the client side (your application).

Clue displays the output from your program to a list along with information like:

As you can see, I meant for this to be used by BeOS C++ programs that use OOP (classes, methods, and that sort of thing).

I've included a sample app folder that demonstrates how you would use Clue. The "Clue.h" header file has the definitions for the "libClue2.so". You should install "libClue2.so" into your "home/config/lib" folder before using it.



Clue Monitoring


There are two different looks for the windows that Clue can show: the Live! window, or the File window. The Live! window will receive current application "Fingerprints", while the File version of the Clue window allows viewing of Exported information from Clue. The File window works the same as the Live! window except that the Start, Stop, Category, and Event buttons are missing (as there is no need for them).

To begin monitoring applications, either select Start from the File menu, or click the green button. To stop monitoring, select Stop from the File menu, or click the red button.

Below is an image of the two buttons, and shows that monitoring is currently on:

StartStop.gif

Clue receives "Fingerprints" from client applications and displays them in its window. Fingerprints can arrive from many different apps at the same time. Using the filtering capabilities, you can determine what information is sent to Clue from client applications. Each Fingerprint that is sent from the client includes a Category and Event. Using these two items, you can control how much information client applications have to send. Selecting fewer Events from each Category will reduce the CPU overhead. This is different than most other BeOS debug output type applications, where they merely use a BMessenger to send all information to the monitor, and then do filtering. That can be a lot of wasted CPU cycles. Clue instead prevents those messages from being sent in the first place, thereby saving CPU resources.

Below is an image of what the filtering controls look like:

Filter.gif

There are ten different Clue Categories. Each Category has twelve Events that can be selected. Selecting an Event from one Category has no effect on any other Category.

Below is a what the Category menu looks like:

CategoryMenu.gif

The check next to a Category indicates which Category the Event buttons are representing. Whatever Category is shown in the menu doesn't mean that only those Events are being captured for that Category, it just determines the state of the Event buttons.

Here is a short description of what each Category represents:

Category Icon Description Command Constant
Application Things that are related to BApplication objects. CC_APPLICATION
General Things that might not fall under any other Category. CC_GENERAL
Interface Things related to BWindow, BVIew, GUI type objects. CC_INTERFACE
Keyboard Keyboard related Events. CC_KEYBOARD
Media Things related to processing multi-media. CC_MEDIA
Mouse Things related to processing mouse handling. CC_MOUSE
Network Socket programming messages. CC_NETWORK
Printing Things related to printing and its setup. CC_PRINTING
Storage Things related to working with files/documents on a disk. CC_STORAGE
Support Things related to the BeOS Support kit objects. CC_SUPPORT



The last four entries on the Category menu allow easy modification of a whole set of Events:

Entry Name Description
Select All Events All Categories Allows you to filter all available Events for all available Categories.
Select All Events Current Category Allows you to turn on filtering for all twelve of the Events for the currently shown Category, regardless of whether an Event was already on or off.
Unselect All Events All Categories Turns off filtering for all Events in all Categories, almost like Stopping Clue.
Unselect All Events Current Category Turns off filtering for the currently shown Category.



Here is a short description of what each of the twelve Events represent:

Command Constant Icon Description
CE_BIRTH A class instantiation, not necessarily the constructor though.
CE_DEATH A class deletion, not necessarily the destructor though.
CE_ENTER A class' method is just beginning.
CE_EXIT A class' method is finished.
CE_OK Code worked as expected.
CE_INFO Here is some information about a variable or what's going on in the code.
CE_WARNING Some piece of code didn't work quite as expected.
CE_ERROR Some type of fatal error happened in the code.
CE_SUCCEEDED Something worked as expected, an audit event.
CE_FAILED Something didn't work as expected, an audit event.
CE_TIMER Something time sensitive happened.
CE_OBJECT Information regarding a code object, like a BMessage.


Left-clicking on one of the Event buttons either selects or unselects that Event from being filtered for the currently shown Category. If you right-click, that will select or unselect that Event for all Categories (i.e. - for all 10 Categories, regardless of which Category is currently selected). A selected Event button will be darker in color than a non-selected Event.

In the image below, the CE_TIMER Event is unselected, while the CE_OBJECT Event is selected:

SelectedUnselected.gif

Clue separates Fingerprint entries by using the TeamID to add a new entry into the Teams listbox if needed. The Teams list box has 5 categories of information it shows for each entry.

Here is what the Teams listview looks like:

TeamList.gif

A single line under the "Team ID" indicates that that application is still running, and will automatically be removed when that application quits. In the picture above, the "Team ID" of 1454, shows that that application is still running.

You can right-click on a team entry. A menu like this will show, allowing you different options for the team:

TeamMenu.gif

Here is a short description of what each of the twelve Events represent:

Menu Entry Description
Clear clue list Removes and deletes all fingerprints for this team.
Edit properties Brings up a window that allows slight modifications of a teams settings.
Activate Make this team the application with the focus. Only applicable if the team has a BWindow.
Delete this entry Removes and deletes this team from Clue. This automatically deletes all fingerprints as well.



The image below shows the categories that each Team entry has:

TeamCLVHeader.gif

Column Name Description
Visible Indicates whether the Teams tab view is showing. A red dot ( ) indicates it is shown.
Icon Displays the client applications icon. If it can't be found, the default image  is shown.
Team ID Displays the BeOS team id and is unique for each application running under BeOS.
Name Displays the applications name.
Queue Length Indicates how many Fingerprints are kept around for this team.


You can make any team entries' tab view Visible or not, but either double-clicking, or hitting the space or Enter keys while it's selected. You can also drag a previously selected team to the desktop or another application. This will send all of that teams information to the dropped application.

You can show/hide any of the 5 team categories by right-clicking on the column header, and check/uncheck an entry. Below is an image of what that menu looks like:

TeamCLVMenu.gif

You can reorder any column by left-clicking on it and dragging it to the new position.

Right now, Clue is hard coded to only keep track of 5,000 most recent Fingerprints. On the 5,001st Fingerprint, it will remove the very 1st Fingerprint entry, and so on.

Clue allows viewing of a Teams Fingerprints by using the Team Tab view:

TeamTab2.gif

Each Team Tab shown displays the applications icon, and the text "Team: TEAM_ID" where TEAM_ID is the Team ID from the Team list that it represents. The Team Tab view displays the Fingerprints that have first passed the filter. After that, the entries that are displayed are determined by each Teams view filter (this feature is not quite yet implemented in this release). The Fingerprint entries are displayed in a list in sequence by when they arrived, NOT by the information contained within (ie the Sequence number). When you select an entry, if it has "Detail" data, it will be displayed in the text box below the list. The list is a multi-select list. When you click and drag previously selected fingerprints, you can drop them on the desktop or another application.

The Team Tab view list displays eleven different columns:

Viewables.gif

Column Name Description
Category Displays an icon representing which Category this Fingerprint belongs to.
Event Displays an icon representing which Event this Fingerprint represents.
Method This is the class method where the Fingerprint was generated.
Class This is the name of the class that contained the method that generated the Event.
File This is the name of the file where the method is defined.
Line The line number within the file where the TRACE_X call is located.
Thread ID The BeOS thread from which the Fingerprint was generated.
Sequence A unique sequence number for this application that keeps incrementing by one each time a TRACE_X method is called.
Date The BeOS system date that identifies when the Fingerprint was generated. In Day/Month/Year format.
Time The BeOS time stamp that further identifies when the Fingerprint was generated. In 24 hour format: Hour:Minute:Second.Millisecond.
Description Some information the programmer wanted shown with this Event.

You can show/hide any of the eleven columns by right-clicking on the column header, and check/uncheck an entry. Below is an image of what that menu looks like:

ClueCLVMenu.gif

You can reorder any column by left-clicking on it and dragging it to the new position.

With heavy traffic coming into Clue, sometimes the UI will freeze. This is normal and no data should be lost. I've sent quite a bit of data to the program over the course of 48 hours, to a total of over 4 million messages without a memory leak, so I believe it to be quite robust. The maximum Description and Detail length you can send is somewhat unlimited, but you should keep them as short as possible as this data has to cross the system from your app to Clue. As you can probably imagine, if the program holds up to 5,000 entries, with each "Detail" and/or "Description" maxed out at 1,024 bytes (and that doesn't include the other record information!), you can easily suck up several megabytes of memory rather quickly!!!



Programming for Clue

To allow sending data from your app to Clue, you must first include the "Clue.h" file in your .cpp file by using this line: #include "Clue.h". You also need to "#define CLUE" before your "#include", otherwise tracing will be removed from the code for that file. Make sure that you've included all other header files before including "Clue.h"!!!

An example of this is shown below:

#include <Application.h>
#include <Window.h>
#include <View.h>

#define CLUE //define this to allow sending of Clue messages
           //comment it out to remove tracing in this file
#include "Clue.h" //tracing definitions and constants

There are currently four different TRACE_X calls:

All of the macros take some arguments that you supply that identify that Fingerprint. It is important to note that each macro is independent of any other. That is, you don't need to have used the TRACE_CLASS macro in order to use the TRACE_METHOD macro, you can use them in any combination! The TRACE_OBJECT, TRACE_SIMPLE, and TRACE_METHOD macros take a parameter list that is enclosed by double opening "((" and double closing "))" brackets, while the TRACE_CLASS macro uses a single open "(" and close ")" bracket.


TRACE_OBJECT((1, 2, 3 [, 4]))

Below are the ARGS you pass to TRACE_OBJECT:

Parameter Data Type Required? Description
1 ClueCategory Yes Must be one of the following: CC_GENERAL, CC_APPLICATION, CC_INTERFACE, CC_MEDIA, CC_STORAGE, CC_SUPPORT, CC_NETWORK, CC_MOUSE, CC_KEYBOARD, or CC_PRINTING.
2 (macro defined) Yes Must be one of the following: CR_OK, CR_INFO, CR_WARNING, CR_ERROR, CR_SUCCEEDED, CR_FAILED, CR_ENTER, CR_EXIT, CR_TIMER, CR_BIRTH, CR_DEATH, or CR_OBJECT. This entry supplies the Event, Line number, File name, and Method name.
3 (see Description) Yes See Appendix A for a list of supported objects.
4 const char * No This is the description that will be part of the Fingerprint. Don't put the carriage return (\r) or newline (\n) statements in your string.


Examples of this call are given below:

TRACE_OBJECT ((CC_APPLICATION, CR_OBJECT, &msg, "Test the BMessage handling."));
TRACE_OBJECT ((CC_APPLICATION, CR_OBJECT, &msg));


TRACE_OBJECT doesn't take ownership of the parameters passed. It will make copies of whatever it needs without changing the passed object. TRACE_OBJECT doesn't work for non-class funcations or subs. You can use as many of these as you would like per method. TRACE_OBJECT is now a very powerful tool to use to figure out the state of many of the BeOS classes, enums, and structs, just by passing it an object.

Be aware that TRACE_OBJECT should not be used in situations where performance timing is a high priority. This is because TRACE_OBJECT calls many methods for the given object, as well as any base classes that the object may have!


TRACE_SIMPLE((1, 2 [, 3 [, 4, ...]]))

Below are the ARGS you pass to TRACE_SIMPLE:

Parameter Data Type Required? Description
1 ClueCategory Yes Must be one of the following: CC_GENERAL, CC_APPLICATION, CC_INTERFACE, CC_MEDIA, CC_STORAGE, CC_SUPPORT, CC_NETWORK, CC_MOUSE, CC_KEYBOARD, or CC_PRINTING.
2 (macro defined) Yes Must be one of the following: CR_OK, CR_INFO, CR_WARNING, CR_ERROR, CR_SUCCEEDED, CR_FAILED, CR_ENTER, CR_EXIT, CR_TIMER, CR_BIRTH, CR_DEATH, or CR_OBJECT. This entry supplies the Event, Line number, File name, and Method name.
3 const char * No This is the description that will be part of the Fingerprint. This text may also define a printf like string. Don't put the carriage return (\r) or newline (\n) statements in your string.
4 or more (standard) No These are the parameters to the printf defined string in parameter 3.


Examples of this call are given below:

TRACE_SIMPLE ((CC_APPLICATION, CR_INFO, "Hooray! We're on our way."));
TRACE_SIMPLE ((CC_APPLICATION, CR_INFO, "BPoint: [%0.f, %0.f]", point.x, point.y));
TRACE_SIMPLE ((CC_APPLICATION, CR_INFO));


TRACE_SIMPLE doesn't take ownership of the parameters passed. It will make copies of whatever it needs without changing the passed object. TRACE_SIMPLE doesn't work for non-class funcations or subs. You can use as many of these as you would like per method.


TRACE_METHOD((1, 2 [, 3 [, 4, ...]]))

Below are the ARGS you pass to TRACE_METHOD:

Parameter Data Type Required? Description
1 ClueCategory Yes Must be one of the following: CC_GENERAL, CC_APPLICATION, CC_INTERFACE, CC_MEDIA, CC_STORAGE, CC_SUPPORT, CC_NETWORK, CC_MOUSE, CC_KEYBOARD, or CC_PRINTING.
2 (macro defined) Yes Must be REPORT_METHOD.
3 const char * No This is the description that will be part of the Fingerprint. This text may also define a printf like string. Don't put the carriage return (\r) or newline (\n) statements in your string.
4 or more (standard) No These are the parameters to the printf defined string in parameter 3.


Examples of this call are given below:

TRACE_METHOD ((CC_INTERFACE, REPORT_METHOD));
TRACE_METHOD ((CC_INTERFACE, REPORT_METHOD, "name = %s", name));
TRACE_METHOD ((CC_INTERFACE, REPORT_METHOD, "CWindow::QuitRequested"));


TRACE_METHOD doesn't take ownership of the parameters passed. It will make copies of whatever it needs without changing the passed object. This statement is typically placed as the very first statement in your method. You can only use one of these statements per method. When a TRACE_METHOD call exits (CE_EXIT), the time it took to perform that method/function/sub, is give in the description for the event in hours:minutes:seconds.microseconds. This will give you some rough performance statistics on your code.


TRACE_CLASS(1)

Below are the ARGS you pass to TRACE_CLASS:

Parameter Data Type Required? Description
1 ClueCategory Yes Must be one of the following: CC_GENERAL, CC_APPLICATION, CC_INTERFACE, CC_MEDIA, CC_STORAGE, CC_SUPPORT, CC_NETWORK, CC_MOUSE, CC_KEYBOARD, or CC_PRINTING. Choose which one depending on what is the major functionality of this class.


An example of this call in a class definition is shown below:

class CApp : public BApplication
{
   public:
      CApp (void);
   private:
      TRACE_CLASS (CC_APPLICATION);
};


TRACE_CLASS doesn't take ownership of the parameters passed. It will make copies of whatever it needs without changing the passed object. This statement should be placed in your class definition. You should have only one TRACE_CLASS statement defined per class. Notice that the TRACE_CLASS macro uses only a single bracket "(parameter)", not double "((parameters))" like the other three macros.


Special Thanks


Thanks to those of you who have written letting me know your appreciation for writing Clue. I also would like to thank those who put some time and effort into translating all of the UI strings into all of the different languages!

Also, thanks to Erik at www.cubelab.com for some of the wonderful icons that are used in Clue!


Miscellaneous


The settings for Clue are kept in the file: "/boot/home/config/settings/Clue_settings". Clue data files saved with the 2000.7.14 version may not open correctly with the latest version and are unsupported at this time.


History of Clue


2.0.0 Development (September 30, 2002)
For a while I had abonded development of Clue because lack of interest in BeOS in general. I had always envisioned writing code to inspect every BeOS object imaginable. It has been nagging me that I never finished the project, so I finally set out to finish what I started almost 3 years ago. Most of the new inspectable objects in this dev release only have the most basic wrappers around them, I will fill them out in further releases. I also wanted to be able to change what objects TRACE_OBJECT would send, so I've added a UI that can allow the user to pick and choose what objects are sent, as well as what functions Clue will inspect on classes. That way, the user can select only those items they are interested in. I also changed how I version Clue. Previously I had been using the 2002.9.30 format (obviously based on the release date), but have now changed to the standard of just incrementing the version number to show how much of an improvement went into the release. I started at 2.0.0 with the idea that it will increment to 2.x.x as I fill out the wrappers for the new objects. Once that is done, I will release a 3.0 version. And that might be it, I don't know what else I would code into Clue. You tell me.

2001.5.16 Beta2
Major additions to the client side library, libClue2.so. This included inspection code on over 85 BeOS objects! I also added a drag-and-drop support to the team and fingerprint listings, as well as clipboard support. Minor other little tweaks. Updated this documentation to add some things I missed last time. Erik at www.cubelab.de gave me some updated looking icons. I will add other traceable objects as time permits. Only a handful of the currently traceable objects have had any kind of testing, so please report to me any incorrect behavior. Improved the class/method name parsing. Therefore, I feel it is somewhat safe to use in non-class methods and functions. There still may be some parsing problems with different function declarations. Changed the Team Tabs listview to be multi-select.

2001.5.4 Beta
I've been slowly putting in minor tweaks into the application and added the Czech localization. The first real version of this documentation is ready to go.

2001.4.4 Alpha
I hadn't updated Clue for quite a long time, not that I hadn't been coding on it. I added some relatively minor tweaks to the Teams listing view. Also added the capability to adjust almost all of Clues UI colors. The big addition was the ability to trace BMessages and their contents. This information is sent to a TextView that allows easy perusal of its contents. The documentation is still unfinished. Got rid of the dependance on the BTranslationUtils to load resources, which removed some of the libraries that needed to be loaded in its address space (quite a few considering all of the translators that are available).

2000.7.14
Major recoding of the original Clue application. The only thing that remained somewhat the same was the way the message were delivered to the application and some of the internal underpinnings.

2000.5.16 Development
Early release of the 2000.7.14 version: *better handling of multiple teams *better management of what Clues you want to report *revamped UI *improved client-side performance

Sometime in late 1999
This was the very first start of what was to become Clue. I had originally named it Gossip, but changed the name as there was another BeOS app named Gossip. I wasn't really sure how far I'd go with the app, as I was still learning the BeOS API. I first showed it to the Seattle Be Users Group where people asked about if I had it available for download somewhere. So I figured that if those few people were interested, others would be too, but it wasn't a polished application yet.


Cheers,
Jeff


Appendix A


There are currently 309 traceable BeOS objects (previous version had only 85) that you can use with TRACE_OBJECT. Here are the current list of those objects:

Type Description
77 Enums alignment, alpha_function, border_style, B_TRANSLATION_ERROR, buffer_layout, buffer_orientation, button_width, cap_mode, color_control_layout, color_space, cpu_type, data_bits, data_rate, directory_which, direct_buffer_state, direct_driver_state, drawing_mode, file_panel_mode, file_panel_button, filter_result, font_direction, font_file_format, font_metric_mode, gs_attributes, hash_mark_location, icon_size, image_type, info_location, input_device_notification, input_device_type, input_method_op, interpolation_mode, join_mode, list_view_type, mail_flags, media_display_flags, media_file_accept_format_flags, media_flags, media_format_family, media_format_flags, media_frame_flags, media_multi_channels, media_multi_matrix, media_parameter_flags, media_producer_status, media_realtime_flags, media_seek_type, media_type, menu_bar_border, menu_layout, message_delivery, message_source, midi_axe, mpeg_id, node_flavor, node_kind, orientation, parity_mode, query_op, reverb_mode, source_alpha, stop_bits, swap_action, status_t, synth_mode tab_position, thread_state, thumb_style, timecode_type, undo_state, value_kind, version_kind, video_orientation, window_alignment, window_feel, window_look, window_type.
135 Class' BAlert, BAppFileInfo, BApplication, BAutolock, BBitmap, BBitmapStream, BBox, BBuffer, BBufferConsumer, BBufferGroup, BBufferIO, BBufferProducer BButton, BChannelControl, BChannelSlider, BCheckBox, BClipboard, BColorControl, BContinuousParameter, BControl, BControllable, BDirectory, BDirectWindow, BDiscreteParameter, BDragger, BEntry, BEntryList, BFile, BFileGameSound, BFileInterface, BFilePanel, BFlattenable, BFont, BGameSound, BGLView, BHandler, BInputDevice, BInvoker, BJoystick, BList, BListItem, BListView, BLocker, BLooper, BMediaAddOn, BMediaDecoder, BMediaEncoder, BMediaEventLooper, BMediaFile, BMediaFiles, BMediaFormats, BMediaNode, BMediaRoster, BMediaTheme, BMediaTrack, BMenu, BMenuBar, BMenuField, BMenuItem, BMessage, BMessageFilter, BMessageQueue, BMessageRunner, BMessenger, BMidi, BMidiPort, BMidiStore, BMidiSynth, BMidiSynthFile, BMidiText, BMimeType, BMultiChannelControl, BNode, BNodeInfo, BNullParameter, BOptionControl, BOptionPopUp, BOutlineListView, BParameter, BParameterGroup, BParameterWeb, BPath, BPicture, BPictureButton, BPoint, BPolygon, BPopUpMenu, BPrintJob, BPropertyInfo, BPushGameSound, BQuery, BRadioButton, BRect, BRegion, BResources, BResourceStrings, BRoster, BSamples, BScreen, BScrollBar, BScrollView, BSeparatorItem, BSerialPort, BShape, BShelf, BSimpleGameSound, BSlider, BSmallBuffer, BSound, BSoundFile, BSoundPlayer, BStatable, BStatusBar, BStopWatch, BStreamingGameSound, BString, BStringItem, BStringView, BSymLink, BSynth, BTab, BTabView, BTextControl, BTextView, BTimeCode, BTimedEventQueue, BTimeSource, BTranslator, BTranslatorRoster, BView, BVolume, BVolumeRoster, BWindow. media_node, unicode_block
97 Structs alert_typeapp_infoarea_infobuffer_clone_infobutton_spacingclipping_rectcolor_mapcompound_typecpu_infodirect_buffer_infodormant_flavor_infodormant_node_infoedge_infoencode_parameters,  entry_ref,  escapement_deltaflavor_infofont_heightgs_attributegs_attribute_infogs_audio_formatGUIDimage_infokey_infokey_maplive_node_infomedia_aiff_descriptionmedia_asf_descriptionmedia_audio_headermedia_avi_descriptionmedia_avr_descriptionmedia_beos_descriptionmedia_codec_infomedia_decode_infomedia_destinationmedia_encode_infomedia_encoded_audio_formatmedia_encoded_audio_headermedia_encoded_video_formatmedia_encoded_video_headermedia_file_formatmedia_file_format_idmedia_formatmedia_format_descriptionmedia_headermedia_header_time_codemedia_inputmedia_misc_descriptionmedia_mpeg_descriptionmedia_multi_audio_infomedia_multistream_formatmedia_multistream_headermedia_node_attributemedia_outputmedia_quicktime_descriptionmedia_raw_audio_formatmedia_raw_video_formatmedia_request_infomedia_seek_tagmedia_sourcemedia_timed_eventmedia_video_display_infomedia_video_headermedia_wav_descriptionmail_notificationmail_pop_accountmouse_mapnode_refoverlay_rect_limitsoverlay_restrictionspatternplatform_typeport_infoproperty_info,  rgb_color,  screen_idscroll_bar_infosem_infosystem_infoteam_infoteam_usage_infotext_runtext_run_arraythread_info  timecode_infotranslation_formatTranslatorBitmaptranslator_infoTranslatorGroupsTranslatorSoundTranslatorStyledTextRecordHeaderTranslatorStyledTextStreamHeaderTranslatorStyledTextTextHeaderTranslatorStyledTextStyleHeadertuned_font_infovalue_infoversion_info


Enums should be passed by value, while class' and structs should be passed in as pointers to TRACE_OBJECT.

TRACE_OBJECT ((CC_GENERAL, CR_OBJECT, &msg, "pass by pointer class', like a BMessage."));
TRACE_OBJECT ((CC_GENERAL, CR_OBJECT, wf, "pass by value enums, like window_feel"));
TRACE_OBJECT ((CC_GENERAL, CR_OBJECT, &rgb, "pass by pointer structs', like a rgb_color."));