12 #define WIN32_LEAN_AND_MEAN
23 #define SCHEMA_STRINGS
24 #define TMT_ENUMDEF (0x0D) // undocumented
25 #define TMT_ENUMVAL (0x0E) // undocumented
26 #define TMT_ENUM (0x0F) // undocumented
31 typedef std::map
<int, std::wstring
> tm_enum_t
;
32 typedef std::map
<std::wstring
, tm_enum_t
> tm_enums_t
;
39 tm_enums_t::iterator enum_type
;
42 static tm_enums_t tm_enums
;
44 typedef std::list
<tm_property_t
> tm_properties_t
;
46 static tm_properties_t tm_properties
;
48 typedef std::map
<int, std::wstring
> tm_states_t
;
49 typedef std::map
<std::wstring
, tm_states_t
> tm_state_enums_t
;
51 static tm_state_enums_t tm_state_enums
;
56 tm_state_enums_t::iterator states
;
59 typedef std::map
<int, tm_part_t
> tm_parts_t
;
61 typedef std::map
<std::wstring
, tm_parts_t
> tm_classes_t
;
63 static tm_classes_t tm_classes
;
71 print(std::FILE * out_
): m_out(out_
) { }
76 public std::unary_function
<tm_property_t
, void>
79 wchar_t const * type_name(const tm_property_t
& property_
)
81 switch(property_
.type
)
83 case TMT_STRING
: return L
"LPWSTR";
84 case TMT_INT
: return L
"int";
85 case TMT_BOOL
: return L
"BOOL";
86 case TMT_COLOR
: return L
"COLORREF";
87 case TMT_MARGINS
: return L
"MARGINS";
88 case TMT_FILENAME
: return L
"LPWSTR";
89 case TMT_SIZE
: return L
"SIZE";
90 case TMT_POSITION
: return L
"POINT";
91 case TMT_RECT
: return L
"RECT";
92 case TMT_FONT
: return L
"LOGFONT";
93 case TMT_INTLIST
: return L
"INTLIST";
94 case TMT_ENUM
: return property_
.enum_type
->first
.c_str();
95 default: return L
"<unknown>";
100 property_print(std::FILE * out_
): print(out_
) { }
102 void operator()(const tm_property_t
& property_
)
108 type_name(property_
),
109 property_
.name
.c_str(),
117 public std::unary_function
<tm_parts_t::value_type
, void>
120 part_print(std::FILE * out_
): print(out_
) { }
122 void operator()(const tm_parts_t::value_type
& part_
)
128 part_
.second
.name
.c_str(),
130 part_
.second
.states
== tm_state_enums
.end() ?
132 part_
.second
.states
->first
.c_str()
139 public std::unary_function
<tm_classes_t::value_type
, void>
142 class_print(std::FILE * out_
): print(out_
) { }
144 void operator()(const tm_classes_t::value_type
& class_
)
146 std::fwprintf(m_out
, L
"%s\n", class_
.first
.c_str());
150 class_
.second
.begin(),
157 class schema_scan
: public std::unary_function
<struct TMPROPINFO
, void>
173 tm_parts_t
* p_class
;
174 tm_states_t
* p_states
;
178 bool has_suffix(const std::wstring
& name_
, const std::wstring
& suffix_
)
180 if(name_
.length() <= suffix_
.length()) return false;
184 name_
.end() - suffix_
.length(),
191 schema_scan(): m_state(at_none
) { }
193 void operator()(const struct TMPROPINFO
& prop_
)
195 static const std::wstring
parts_suffix(L
"PARTS");
196 static const std::wstring
states_suffix(L
"STATES");
198 std::wstring
name(prop_
.pszName
);
200 // Compound declaration
201 if(prop_
.sEnumVal
== TMT_ENUMDEF
&& prop_
.bPrimVal
== TMT_ENUMDEF
)
204 if(has_suffix(name
, parts_suffix
))
211 std::wstring(name
.begin(), name
.end() - parts_suffix
.length())
216 else if(has_suffix(name
, states_suffix
))
223 std::wstring(name
.begin(), name
.end() - states_suffix
.length())
231 m_cur
.p_enum
= &(tm_enums
[name
] = tm_enum_t());
234 // Enumeration member
235 else if(prop_
.bPrimVal
== TMT_ENUMVAL
) switch(m_state
)
237 // enumeration member
240 (*m_cur
.p_enum
)[prop_
.sEnumVal
] = name
;
249 part
.states
= tm_state_enums
.end();
250 (*m_cur
.p_class
)[prop_
.sEnumVal
] = part
;
257 (*m_cur
.p_states
)[prop_
.sEnumVal
] = name
;
262 else if(prop_
.sEnumVal
== prop_
.bPrimVal
)
273 tm_property_t property
;
275 property
.name
= name
;
276 property
.id
= prop_
.sEnumVal
;
277 property
.type
= prop_
.bPrimVal
;
279 if(prop_
.bPrimVal
== TMT_ENUM
)
280 property
.enum_type
= tm_enums
.find(name
);
282 tm_properties
.push_back(property
);
287 struct state_mapping_t
294 static const tmdump::state_mapping_t state_map
[] =
296 { L
"BUTTON", 0, NULL
},
297 { NULL
, BP_CHECKBOX
, L
"CHECKBOX" },
298 { NULL
, BP_GROUPBOX
, L
"GROUPBOX" },
299 { NULL
, BP_PUSHBUTTON
, L
"PUSHBUTTON" },
300 { NULL
, BP_RADIOBUTTON
, L
"RADIOBUTTON" },
301 { L
"CLOCK", CLP_TIME
, L
"CLOCK" },
302 { L
"COMBOBOX", CP_DROPDOWNBUTTON
, L
"COMBOBOX" },
303 { L
"EDIT", EP_EDITTEXT
, L
"EDITTEXT" },
304 { L
"EXPLORERBAR", 0, NULL
},
305 { NULL
, EBP_HEADERCLOSE
, L
"HEADERCLOSE" },
306 { NULL
, EBP_HEADERPIN
, L
"HEADERPIN" },
307 { NULL
, EBP_IEBARMENU
, L
"IEBARMENU" },
308 { NULL
, EBP_NORMALGROUPCOLLAPSE
, L
"NORMALGROUPCOLLAPSE" },
309 { NULL
, EBP_NORMALGROUPEXPAND
, L
"NORMALGROUPEXPAND" },
310 { NULL
, EBP_SPECIALGROUPCOLLAPSE
, L
"SPECIALGROUPCOLLAPSE"},
311 { NULL
, EBP_SPECIALGROUPEXPAND
, L
"SPECIALGROUPEXPAND" },
312 { L
"HEADER", 0, NULL
},
313 { NULL
, HP_HEADERITEM
, L
"HEADERITEM" },
314 { NULL
, HP_HEADERITEMLEFT
, L
"HEADERITEMLEFT" },
315 { NULL
, HP_HEADERITEMRIGHT
, L
"HEADERITEMRIGHT" },
316 { NULL
, HP_HEADERSORTARROW
, L
"HEADERSORTARROW" },
317 { L
"LISTVIEW", LVP_LISTITEM
, L
"LISTITEM " },
318 { L
"MENU", 0, NULL
},
319 { NULL
, MP_MENUBARDROPDOWN
, L
"MENU" },
320 { NULL
, MP_MENUBARITEM
, L
"MENU" },
321 { NULL
, MP_CHEVRON
, L
"MENU" },
322 { NULL
, MP_MENUDROPDOWN
, L
"MENU" },
323 { NULL
, MP_MENUITEM
, L
"MENU" },
324 { NULL
, MP_SEPARATOR
, L
"MENU" },
325 { L
"MENUBAND", MDP_NEWAPPBUTTON
, L
"MENUBAND" },
326 { L
"PAGE", 0, NULL
},
327 { NULL
, PGRP_DOWN
, L
"DOWN" },
328 { NULL
, PGRP_DOWNHORZ
, L
"DOWNHORZ" },
329 { NULL
, PGRP_UP
, L
"UP" },
330 { NULL
, PGRP_UPHORZ
, L
"UPHORZ" },
331 { L
"REBAR", RP_CHEVRON
, L
"CHEVRON" },
332 { L
"SCROLLBAR", 0, NULL
},
333 { NULL
, SBP_ARROWBTN
, L
"ARROWBTN" },
334 { NULL
, SBP_LOWERTRACKHORZ
, L
"SCROLLBAR" },
335 { NULL
, SBP_LOWERTRACKVERT
, L
"SCROLLBAR" },
336 { NULL
, SBP_THUMBBTNHORZ
, L
"SCROLLBAR" },
337 { NULL
, SBP_THUMBBTNVERT
, L
"SCROLLBAR" },
338 { NULL
, SBP_UPPERTRACKHORZ
, L
"SCROLLBAR" },
339 { NULL
, SBP_UPPERTRACKVERT
, L
"SCROLLBAR" },
340 { NULL
, SBP_SIZEBOX
, L
"SIZEBOX" },
341 { L
"SPIN", 0, NULL
},
342 { NULL
, SPNP_DOWN
, L
"DOWN" },
343 { NULL
, SPNP_DOWNHORZ
, L
"DOWNHORZ" },
344 { NULL
, SPNP_UP
, L
"UP" },
345 { NULL
, SPNP_UPHORZ
, L
"UPHORZ" },
346 { L
"STARTPANEL", 0, NULL
},
347 { NULL
, SPP_LOGOFFBUTTONS
, L
"LOGOFFBUTTONS" },
348 { NULL
, SPP_MOREPROGRAMSARROW
, L
"MOREPROGRAMSARROW" },
350 { NULL
, TABP_TABITEM
, L
"TABITEM" },
351 { NULL
, TABP_TABITEMBOTHEDGE
, L
"TABITEMBOTHEDGE" },
352 { NULL
, TABP_TABITEMLEFTEDGE
, L
"TABITEMLEFTEDGE" },
353 { NULL
, TABP_TABITEMRIGHTEDGE
, L
"TABITEMRIGHTEDGE" },
354 { NULL
, TABP_TOPTABITEM
, L
"TOPTABITEM" },
355 { NULL
, TABP_TOPTABITEMBOTHEDGE
, L
"TOPTABITEMBOTHEDGE" },
356 { NULL
, TABP_TOPTABITEMLEFTEDGE
, L
"TOPTABITEMLEFTEDGE" },
357 { NULL
, TABP_TOPTABITEMRIGHTEDGE
, L
"TOPTABITEMRIGHTEDGE" },
358 { L
"TOOLBAR", 0, NULL
},
359 { NULL
, TP_BUTTON
, L
"TOOLBAR" },
360 { NULL
, TP_DROPDOWNBUTTON
, L
"TOOLBAR" },
361 { NULL
, TP_SPLITBUTTON
, L
"TOOLBAR" },
362 { NULL
, TP_SPLITBUTTONDROPDOWN
, L
"TOOLBAR" },
363 { NULL
, TP_SEPARATOR
, L
"TOOLBAR" },
364 { NULL
, TP_SEPARATORVERT
, L
"TOOLBAR" },
365 { L
"TOOLTIP", 0, NULL
},
366 { NULL
, TTP_BALLOON
, L
"BALLOON" },
367 { NULL
, TTP_BALLOONTITLE
, L
"BALLOON" },
368 { NULL
, TTP_CLOSE
, L
"CLOSE" },
369 { NULL
, TTP_STANDARD
, L
"STANDARD" },
370 { NULL
, TTP_STANDARDTITLE
, L
"STANDARD" },
371 { L
"TRACKBAR", 0, NULL
},
372 { NULL
, TKP_THUMB
, L
"THUMB" },
373 { NULL
, TKP_THUMBBOTTOM
, L
"THUMBBOTTOM" },
374 { NULL
, TKP_THUMBLEFT
, L
"THUMBLEFT" },
375 { NULL
, TKP_THUMBRIGHT
, L
"THUMBRIGHT" },
376 { NULL
, TKP_THUMBTOP
, L
"THUMBTOP" },
377 { NULL
, TKP_THUMBVERT
, L
"THUMBVERT" },
378 { NULL
, TKP_TICS
, L
"TICS" },
379 { NULL
, TKP_TICSVERT
, L
"TICSVERT" },
380 { NULL
, TKP_TRACK
, L
"TRACK" },
381 { NULL
, TKP_TRACKVERT
, L
"TRACKVERT" },
382 { L
"TREEVIEW", 0, NULL
},
383 { NULL
, TVP_GLYPH
, L
"GLYPH" },
384 { NULL
, TVP_TREEITEM
, L
"TREEITEM" },
385 { L
"WINDOW", 0, NULL
},
386 { NULL
, WP_CAPTION
, L
"CAPTION" },
387 { NULL
, WP_CLOSEBUTTON
, L
"CLOSEBUTTON" },
388 { NULL
, WP_FRAMEBOTTOM
, L
"FRAME" },
389 { NULL
, WP_FRAMELEFT
, L
"FRAME" },
390 { NULL
, WP_FRAMERIGHT
, L
"FRAME" },
391 { NULL
, WP_HELPBUTTON
, L
"HELPBUTTON" },
392 { NULL
, WP_HORZSCROLL
, L
"HORZSCROLL" },
393 { NULL
, WP_HORZTHUMB
, L
"HORZTHUMB" },
394 { NULL
, WP_MAXBUTTON
, L
"MAXBUTTON" },
395 { NULL
, WP_MAXCAPTION
, L
"MAXCAPTION" },
396 { NULL
, WP_MDICLOSEBUTTON
, L
"CLOSEBUTTON" },
397 { NULL
, WP_MDIHELPBUTTON
, L
"HELPBUTTON" },
398 { NULL
, WP_MDIMINBUTTON
, L
"MINBUTTON" },
399 { NULL
, WP_MDIRESTOREBUTTON
, L
"RESTOREBUTTON" },
400 { NULL
, WP_MDISYSBUTTON
, L
"SYSBUTTON" },
401 { NULL
, WP_MINBUTTON
, L
"MINBUTTON" },
402 { NULL
, WP_MINCAPTION
, L
"MINCAPTION" },
403 { NULL
, WP_RESTOREBUTTON
, L
"RESTOREBUTTON" },
404 { NULL
, WP_SMALLCAPTION
, L
"CAPTION" },
405 { NULL
, WP_SMALLCLOSEBUTTON
, L
"CLOSEBUTTON" },
406 { NULL
, WP_SMALLFRAMEBOTTOM
, L
"FRAME" },
407 { NULL
, WP_SMALLFRAMELEFT
, L
"FRAME" },
408 { NULL
, WP_SMALLFRAMERIGHT
, L
"FRAME" },
409 { NULL
, WP_SMALLMAXCAPTION
, L
"MAXCAPTION" },
410 { NULL
, WP_SMALLMINCAPTION
, L
"MINCAPTION" },
411 { NULL
, WP_SYSBUTTON
, L
"SYSBUTTON" },
412 { NULL
, WP_VERTSCROLL
, L
"HORZSCROLL" },
413 { NULL
, WP_VERTTHUMB
, L
"HORZTHUMB" },
416 class state_link
: public std::unary_function
<struct state_mapping_t
, void>
419 tm_classes_t::iterator m_class
;
422 void operator()(const struct state_mapping_t
& mapping_
)
424 // switch to a new class
425 if(mapping_
.classname
)
426 m_class
= tm_classes
.find(std::wstring(mapping_
.classname
));
428 // no mapping, or class not found
429 if(mapping_
.states
== NULL
|| m_class
== tm_classes
.end()) return;
431 tm_state_enums_t::iterator states
=
432 tm_state_enums
.find(std::wstring(mapping_
.states
));
434 // unknown set of states
435 if(states
== tm_state_enums
.end()) return;
437 tm_parts_t::iterator part
= m_class
->second
.find(mapping_
.partid
);
440 if(part
== m_class
->second
.end()) return;
443 part
->second
.states
= states
;
448 int main(int argc
, char * argv
[])
452 struct TMSCHEMAINFO
const & schema
= *GetSchemaInfo();
454 // build the tables of properties, classes, parts and states
458 schema
.pPropTable
+ schema
.iPropCount
,
459 tmdump::schema_scan()
462 // link parts to states
466 tmdump::state_map
+ sizeof(tmdump::state_map
) / sizeof(tmdump::state_map
[0]),
470 ::InitCommonControls();
471 ::SetThemeAppProperties(STAP_ALLOW_NONCLIENT
| STAP_ALLOW_CONTROLS
);
473 // dump the current values of all properties
476 tmdump::tm_classes_t::iterator p
= tmdump::tm_classes
.begin();
477 p
!= tmdump::tm_classes
.end();
481 const std::wstring
& class_name
= p
->first
;
483 // open the theme data for the current class
489 htheme_t(HTHEME handle_
): m_handle(handle_
) { }
490 ~htheme_t() { ::CloseThemeData(m_handle
); }
492 operator HTHEME() { return m_handle
; }
494 data
= ::OpenThemeData(NULL
, class_name
.c_str());
502 L
"OpenThemeData(\"%s\") failed, error %d\n",
511 std::fwprintf(stdout
, L
"%s\n", p
->first
.c_str());
513 // dump system properties
516 tmdump::tm_properties_t::iterator p
= tmdump::tm_properties
.begin();
517 p
!= tmdump::tm_properties
.end();
531 std::fwprintf(stdout
, L
"\t%s = ", p
->name
.c_str());
539 case TMT_FILENAME
: // FIXME
542 if(FAILED(hres
= GetThemeSysString(data
, p
->id
, buffer
, 256))) break;
543 std::fwprintf(stdout
, L
"string: \"%s\"", buffer
);
551 if(FAILED(hres
= GetThemeSysInt(data
, p
->id
, &val
))) break;
552 std::fwprintf(stdout
, L
"int: %d", val
);
560 BOOL val
= GetThemeSysBool(data
, p
->id
);
561 if(FAILED(hres
= GetLastError())) break;
562 std::fwprintf(stdout
, L
"bool: %s", val
? L
"true" : L
"false");
571 COLORREF val
= GetThemeSysColor(data
, p
->id
);
573 if(FAILED(hres
= GetLastError())) break;
591 int val
= GetThemeSysSize(data
, p
->id
);
592 if(FAILED(hres
= GetLastError())) break;
593 std::fwprintf(stdout
, L
"size: %d", val
);
601 if(FAILED(hres
= GetThemeSysFont(data
, p
->id
, &val
))) break;
602 std::fwprintf(stdout
, L
"font: %s", val
.lfFaceName
);
606 // enumerated integer
610 if(FAILED(hres
= GetThemeSysInt(data
, p
->id
, &val
))) break;
612 std::fwprintf(stdout
, L
"enum(%s): ", p
->enum_type
->first
.c_str());
614 tmdump::tm_enum_t::iterator enumval
= p
->enum_type
->second
.find(val
);
616 if(enumval
== p
->enum_type
->second
.end())
617 std::fwprintf(stdout
, L
"<%d>", val
);
619 std::fwprintf(stdout
, L
"%s", enumval
->second
.c_str());
625 if(FAILED(hres
)) std::fwprintf(stdout
, L
"<error %08X>", hres
);
627 std::fputwc(L
'\n', stdout
);
632 catch(std::exception e
)
634 std::cerr
<< e
.what() << std::endl
;