📄 themedump.cpp
字号:
#include <cstdlib>
#include <cstdio>
#include <cwchar>
#include <iostream>
#include <exception>
#include <algorithm>
#include <functional>
#include <list>
#include <string>
#include <map>
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <windows.h>
#include <commctrl.h>
#include <uxtheme.h>
#include <tmschema.h>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#define SCHEMA_STRINGS
#define TMT_ENUMDEF (0x0D) // undocumented
#define TMT_ENUMVAL (0x0E) // undocumented
#define TMT_ENUM (0x0F) // undocumented
#include <tmschema.h>
namespace tmdump
{
typedef std::map<int, std::wstring> tm_enum_t;
typedef std::map<std::wstring, tm_enum_t> tm_enums_t;
struct tm_property_t
{
std::wstring name;
int id;
int type;
tm_enums_t::iterator enum_type;
};
static tm_enums_t tm_enums;
typedef std::list<tm_property_t> tm_properties_t;
static tm_properties_t tm_properties;
typedef std::map<int, std::wstring> tm_states_t;
typedef std::map<std::wstring, tm_states_t> tm_state_enums_t;
static tm_state_enums_t tm_state_enums;
struct tm_part_t
{
std::wstring name;
tm_state_enums_t::iterator states;
};
typedef std::map<int, tm_part_t> tm_parts_t;
typedef std::map<std::wstring, tm_parts_t> tm_classes_t;
static tm_classes_t tm_classes;
class print
{
protected:
std::FILE * m_out;
public:
print(std::FILE * out_): m_out(out_) { }
};
class property_print:
public print,
public std::unary_function<tm_property_t, void>
{
private:
wchar_t const * type_name(const tm_property_t& property_)
{
switch(property_.type)
{
case TMT_STRING: return L"LPWSTR";
case TMT_INT: return L"int";
case TMT_BOOL: return L"BOOL";
case TMT_COLOR: return L"COLORREF";
case TMT_MARGINS: return L"MARGINS";
case TMT_FILENAME: return L"LPWSTR";
case TMT_SIZE: return L"SIZE";
case TMT_POSITION: return L"POINT";
case TMT_RECT: return L"RECT";
case TMT_FONT: return L"LOGFONT";
case TMT_INTLIST: return L"INTLIST";
case TMT_ENUM: return property_.enum_type->first.c_str();
default: return L"<unknown>";
}
}
public:
property_print(std::FILE * out_): print(out_) { }
void operator()(const tm_property_t& property_)
{
std::fwprintf
(
m_out,
L"%s\t%s\t%d\n",
type_name(property_),
property_.name.c_str(),
property_.id
);
}
};
class part_print:
public print,
public std::unary_function<tm_parts_t::value_type, void>
{
public:
part_print(std::FILE * out_): print(out_) { }
void operator()(const tm_parts_t::value_type& part_)
{
std::fwprintf
(
m_out,
L"\t%s\t%d\t%s\n",
part_.second.name.c_str(),
part_.first,
part_.second.states == tm_state_enums.end() ?
L"-" :
part_.second.states->first.c_str()
);
}
};
class class_print:
public print,
public std::unary_function<tm_classes_t::value_type, void>
{
public:
class_print(std::FILE * out_): print(out_) { }
void operator()(const tm_classes_t::value_type& class_)
{
std::fwprintf(m_out, L"%s\n", class_.first.c_str());
std::for_each
(
class_.second.begin(),
class_.second.end(),
part_print(m_out)
);
}
};
class schema_scan: public std::unary_function<struct TMPROPINFO, void>
{
private:
enum
{
at_none,
at_enum,
at_parts,
at_states
}
m_state;
union
{
void * p_none;
tm_enum_t * p_enum;
tm_parts_t * p_class;
tm_states_t * p_states;
}
m_cur;
bool has_suffix(const std::wstring& name_, const std::wstring& suffix_)
{
if(name_.length() <= suffix_.length()) return false;
return std::equal
(
name_.end() - suffix_.length(),
name_.end(),
suffix_.begin()
);
}
public:
schema_scan(): m_state(at_none) { }
void operator()(const struct TMPROPINFO& prop_)
{
static const std::wstring parts_suffix(L"PARTS");
static const std::wstring states_suffix(L"STATES");
std::wstring name(prop_.pszName);
// Compound declaration
if(prop_.sEnumVal == TMT_ENUMDEF && prop_.bPrimVal == TMT_ENUMDEF)
{
// class
if(has_suffix(name, parts_suffix))
{
m_state = at_parts;
m_cur.p_class = &
(
tm_classes
[
std::wstring(name.begin(), name.end() - parts_suffix.length())
] = tm_parts_t()
);
}
// states
else if(has_suffix(name, states_suffix))
{
m_state = at_states;
m_cur.p_states = &
(
tm_state_enums
[
std::wstring(name.begin(), name.end() - states_suffix.length())
] = tm_states_t()
);
}
// enumeration
else
{
m_state = at_enum;
m_cur.p_enum = &(tm_enums[name] = tm_enum_t());
}
}
// Enumeration member
else if(prop_.bPrimVal == TMT_ENUMVAL) switch(m_state)
{
// enumeration member
case at_enum:
{
(*m_cur.p_enum)[prop_.sEnumVal] = name;
break;
}
// class part
case at_parts:
{
tm_part_t part;
part.name = name;
part.states = tm_state_enums.end();
(*m_cur.p_class)[prop_.sEnumVal] = part;
break;
}
// state
case at_states:
{
(*m_cur.p_states)[prop_.sEnumVal] = name;
break;
}
}
// Primitive type
else if(prop_.sEnumVal == prop_.bPrimVal)
{
m_state = at_none;
m_cur.p_none = NULL;
}
// Property
else
{
m_state = at_none;
m_cur.p_none = NULL;
tm_property_t property;
property.name = name;
property.id = prop_.sEnumVal;
property.type = prop_.bPrimVal;
if(prop_.bPrimVal == TMT_ENUM)
property.enum_type = tm_enums.find(name);
tm_properties.push_back(property);
}
}
};
struct state_mapping_t
{
LPWSTR classname;
int partid;
LPWSTR states;
};
static const tmdump::state_mapping_t state_map[] =
{
{ L"BUTTON", 0, NULL },
{ NULL, BP_CHECKBOX, L"CHECKBOX" },
{ NULL, BP_GROUPBOX, L"GROUPBOX" },
{ NULL, BP_PUSHBUTTON, L"PUSHBUTTON" },
{ NULL, BP_RADIOBUTTON, L"RADIOBUTTON" },
{ L"CLOCK", CLP_TIME, L"CLOCK" },
{ L"COMBOBOX", CP_DROPDOWNBUTTON, L"COMBOBOX" },
{ L"EDIT", EP_EDITTEXT, L"EDITTEXT" },
{ L"EXPLORERBAR", 0, NULL },
{ NULL, EBP_HEADERCLOSE, L"HEADERCLOSE" },
{ NULL, EBP_HEADERPIN, L"HEADERPIN" },
{ NULL, EBP_IEBARMENU, L"IEBARMENU" },
{ NULL, EBP_NORMALGROUPCOLLAPSE, L"NORMALGROUPCOLLAPSE" },
{ NULL, EBP_NORMALGROUPEXPAND, L"NORMALGROUPEXPAND" },
{ NULL, EBP_SPECIALGROUPCOLLAPSE, L"SPECIALGROUPCOLLAPSE"},
{ NULL, EBP_SPECIALGROUPEXPAND, L"SPECIALGROUPEXPAND" },
{ L"HEADER", 0, NULL },
{ NULL, HP_HEADERITEM, L"HEADERITEM" },
{ NULL, HP_HEADERITEMLEFT, L"HEADERITEMLEFT" },
{ NULL, HP_HEADERITEMRIGHT, L"HEADERITEMRIGHT" },
{ NULL, HP_HEADERSORTARROW, L"HEADERSORTARROW" },
{ L"LISTVIEW", LVP_LISTITEM, L"LISTITEM " },
{ L"MENU", 0, NULL },
{ NULL, MP_MENUBARDROPDOWN, L"MENU" },
{ NULL, MP_MENUBARITEM, L"MENU" },
{ NULL, MP_CHEVRON, L"MENU" },
{ NULL, MP_MENUDROPDOWN, L"MENU" },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -