- 积分
- 2027
- 明经币
- 个
- 注册时间
- 2022-4-4
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 枫叶棋语 于 2025-6-25 15:11 编辑
1. vcpkg 安装 wxwidgets, 命令 vcpkg install wxwidgets:x64-windows-static-md --editable,几分钟时间安装完成,至于为什么选择x64-windows-static-md ,自行百度,静态编译,动态运行;
2. 添加项目配置文件Directory.Build.props ,与解决方案同级目录,配置文件中设置xrc 文件自动编译加载
配置文件如下: 3. 重新编译 wxrc.exe ,至于vcpkg 如何进行修改后重新编译,很简单,
3.1 先卸载 vcpkg remove wxwidgets:x64-windows-static-md --recurse
3.2 将vcpkg 目录下buildtrees\wxwidgets\src\v3.2.7-90467b189b\utils\wxrc文件夹的 wxrc.cpp 替换掉;
3.3 重新编译 vcpkg install wxwidgets:x64-windows-static-md --editable ,可以得到一个新的wxrc.exe ,至于为什么要修改这个工具,自行领会
 - /////////////////////////////////////////////////////////////////////////////
- // Name: wxrc.cpp
- // Purpose: XML resource compiler
- // Author: Vaclav Slavik, Eduardo Marques <edrdo@netcabo.pt>
- // Created: 2000/03/05
- // Copyright: (c) 2000 Vaclav Slavik
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- // For compilers that support precompilation, includes "wx/wx.h".
- #include "wx/wxprec.h"
- // for all others, include the necessary headers
- #ifndef WX_PRECOMP
- #include "wx/app.h"
- #include "wx/log.h"
- #include "wx/wxcrtvararg.h"
- #endif
- #include "wx/cmdline.h"
- #include "wx/xml/xml.h"
- #include "wx/ffile.h"
- #include "wx/filename.h"
- #include "wx/wfstream.h"
- #include "wx/utils.h"
- #include "wx/hashset.h"
- #include "wx/mimetype.h"
- #include "wx/vector.h"
- WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, StringSet);
- class XRCWidgetData
- {
- public:
- XRCWidgetData(const wxString& vname, const wxString& vclass)
- : m_class(vclass), m_name(vname) {
- }
- const wxString& GetName() const { return m_name; }
- const wxString& GetClass() const { return m_class; }
- private:
- wxString m_class;
- wxString m_name;
- };
- #include "wx/arrimpl.cpp"
- WX_DECLARE_OBJARRAY(XRCWidgetData, ArrayOfXRCWidgetData);
- WX_DEFINE_OBJARRAY(ArrayOfXRCWidgetData)
- class XRCWndClassData
- {
- private:
- wxString m_className;
- wxString m_parentClassName;
- StringSet m_ancestorClassNames;
- ArrayOfXRCWidgetData m_wdata;
- void BrowseXmlNode(wxXmlNode* node)
- {
- wxString classValue;
- wxString nameValue;
- wxXmlNode* children;
- while (node)
- {
- if (node->GetName() == wxT("object")
- && node->GetAttribute(wxT("class"), &classValue)
- && node->GetAttribute(wxT("name"), &nameValue))
- {
- m_wdata.Add(XRCWidgetData(nameValue, classValue));
- }
- children = node->GetChildren();
- if (children)
- BrowseXmlNode(children);
- node = node->GetNext();
- }
- }
- public:
- XRCWndClassData(const wxString& className,
- const wxString& parentClassName,
- const wxXmlNode* node) :
- m_className(className), m_parentClassName(parentClassName) {
- if (className == wxT("wxMenu"))
- {
- m_ancestorClassNames.insert(wxT("wxMenu"));
- m_ancestorClassNames.insert(wxT("wxMenuBar"));
- }
- else if (className == wxT("wxMDIChildFrame"))
- {
- m_ancestorClassNames.insert(wxT("wxMDIParentFrame"));
- }
- else if (className == wxT("wxMenuBar") ||
- className == wxT("wxStatusBar") ||
- className == wxT("wxToolBar"))
- {
- m_ancestorClassNames.insert(wxT("wxFrame"));
- }
- else
- {
- m_ancestorClassNames.insert(wxT("wxWindow"));
- }
- BrowseXmlNode(node->GetChildren());
- }
- const ArrayOfXRCWidgetData& GetWidgetData()
- {
- return m_wdata;
- }
- const wxString GeneratedClassName() {
- return (wxT("XRC_") + m_className);
- }
- bool CanBeUsedWithXRCCTRL(const wxString& name)
- {
- if (name == wxT("tool") ||
- name == wxT("data") ||
- name == wxT("unknown") ||
- name == wxT("notebookpage") ||
- name == wxT("separator") ||
- name == wxT("sizeritem") ||
- name == wxT("wxMenu") ||
- name == wxT("wxMenuBar") ||
- name == wxT("wxMenuItem") ||
- name.EndsWith(wxT("Sizer")))
- {
- return false;
- }
- return true;
- }
- void GenerateHeaderCode(wxFFile& file)
- {
- // 添加前缀到生成的类名
- wxString generatedClassName = GeneratedClassName();
- wxString namespaceName = generatedClassName + wxT("_NS");
- file.Write(wxT("class ") + generatedClassName + wxT(" : public ") + m_parentClassName
- + wxT(" {\npublic:\n"));
- // 生成成员变量
- size_t i;
- for (i = 0; i < m_wdata.GetCount(); ++i)
- {
- const XRCWidgetData& w = m_wdata.Item(i);
- if (!CanBeUsedWithXRCCTRL(w.GetClass())) continue;
- if (w.GetName().empty()) continue;
- file.Write(
- wxT(" ") + w.GetClass() + wxT("* ") + w.GetName()
- + wxT(";\n"));
- }
- // 生成初始化方法(保持使用原始类名)
- file.Write(wxT("\npublic:\n void InitWidgetsFromXRC(wxWindow *parent){\n")
- + namespaceName + wxT("::InitXmlResource();\n") +
- wxT(" wxXmlResource::Get()->LoadObject(this,parent,wxT("")
- + m_className // 注意:这里使用原始类名,不是generatedClassName
- + wxT(""), wxT("")
- + m_parentClassName
- + wxT(""));\n"));
- // 生成控件初始化代码
- for (i = 0; i < m_wdata.GetCount(); ++i)
- {
- const XRCWidgetData& w = m_wdata.Item(i);
- if (!CanBeUsedWithXRCCTRL(w.GetClass())) continue;
- if (w.GetName().empty()) continue;
- file.Write(wxT(" ")
- + w.GetName()
- + wxT(" = XRCCTRL(*this,"")
- + w.GetName()
- + wxT("",")
- + w.GetClass()
- + wxT(");\n"));
- }
- file.Write(wxT(" }\n"));
- file.Write(wxT("public:\n"));
- // 生成构造函数(使用带前缀的类名)
- if (m_ancestorClassNames.size() == 1)
- {
- file.Write(
- generatedClassName + // 使用带前缀的类名
- wxT("(") +
- *m_ancestorClassNames.begin() +
- wxT(" *parent=NULL){\n") +
- wxT(" InitWidgetsFromXRC((wxWindow *)parent);\n")
- wxT(" }\n")
- wxT("};\n")
- );
- }
- else
- {
- file.Write(generatedClassName + wxT("(){\n") + // 使用带前缀的类名
- wxT(" InitWidgetsFromXRC(NULL);\n")
- wxT(" }\n")
- wxT("};\n"));
- for (StringSet::const_iterator it = m_ancestorClassNames.begin();
- it != m_ancestorClassNames.end();
- ++it)
- {
- file.Write(generatedClassName + wxT("(") + *it + wxT(" *parent){\n") + // 使用带前缀的类名
- wxT(" InitWidgetsFromXRC((wxWindow *)parent);\n")
- wxT(" }\n")
- wxT("};\n"));
- }
- }
- }
- };
- WX_DECLARE_OBJARRAY(XRCWndClassData, ArrayOfXRCWndClassData);
- WX_DEFINE_OBJARRAY(ArrayOfXRCWndClassData)
- struct ExtractedString
- {
- ExtractedString() : lineNo(-1) {}
- ExtractedString(const wxString& str_,
- const wxString& filename_, int lineNo_)
- : str(str_), filename(filename_), lineNo(lineNo_)
- {
- }
- wxString str;
- wxString filename;
- int lineNo;
- };
- typedef wxVector<ExtractedString> ExtractedStrings;
- class XmlResApp : public wxAppConsole
- {
- public:
- // don't use builtin cmd line parsing:
- virtual bool OnInit() wxOVERRIDE { return true; }
- virtual int OnRun() wxOVERRIDE;
- private:
- void ParseParams(const wxCmdLineParser& cmdline);
- void CompileRes();
- wxArrayString PrepareTempFiles();
- void FindFilesInXML(wxXmlNode* node, wxArrayString& flist, const wxString& inputPath);
- wxString GetInternalFileName(const wxString& name, const wxArrayString& flist);
- wxString GeneratedNamespaceName() const;
- void DeleteTempFiles(const wxArrayString& flist);
- void MakePackageZIP(const wxArrayString& flist);
- void MakePackageCPP(const wxArrayString& flist);
- void MakePackagePython(const wxArrayString& flist);
- void OutputGettext();
- ExtractedStrings FindStrings();
- ExtractedStrings FindStrings(const wxString& filename, wxXmlNode* node);
- bool Validate();
- bool flagVerbose, flagCPP, flagPython, flagGettext, flagValidate, flagValidateOnly;
- wxString parOutput, parFuncname, parOutputPath, parSchemaFile;
- wxArrayString parFiles;
- int retCode;
- ArrayOfXRCWndClassData aXRCWndClassData;
- bool flagH;
- void GenCPPHeader();
- };
- wxIMPLEMENT_APP_CONSOLE(XmlResApp);
- int XmlResApp::OnRun()
- {
- static const wxCmdLineEntryDesc cmdLineDesc[] =
- {
- { wxCMD_LINE_SWITCH, "h", "help", "show help imformation", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
- { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
- { wxCMD_LINE_SWITCH, "e", "extra-cpp-code", "output C++ header file with XRC derived classes" },
- { wxCMD_LINE_SWITCH, "c", "cpp-code", "output C++ source rather than .rsc file" },
- { wxCMD_LINE_SWITCH, "p", "python-code", "output wxPython source rather than .rsc file" },
- { wxCMD_LINE_SWITCH, "g", "gettext", "output list of translatable strings (to stdout or file if -o used)" },
- { wxCMD_LINE_OPTION, "n", "function", "C++/Python function name (with -c or -p) [InitXmlResource]" },
- { wxCMD_LINE_OPTION, "o", "output", "output file [resource.xrs/cpp]" },
- { wxCMD_LINE_SWITCH, "", "validate", "check XRC correctness (in addition to other processing)" },
- { wxCMD_LINE_SWITCH, "", "validate-only", "check XRC correctness and do nothing else" },
- { wxCMD_LINE_OPTION, "", "xrc-schema", "RELAX NG schema file to validate against (optional)" },
- #if 0 // not yet implemented
- { wxCMD_LINE_OPTION, "l", "list-of-handlers", "output list of necessary handlers to this file" },
- #endif
- { wxCMD_LINE_PARAM, NULL, NULL, "input file(s)",
- wxCMD_LINE_VAL_STRING,
- wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_OPTION_MANDATORY },
- wxCMD_LINE_DESC_END
- };
- wxCmdLineParser parser(cmdLineDesc, argc, argv);
- switch (parser.Parse())
- {
- case -1:
- return 0;
- case 0:
- retCode = 0;
- ParseParams(parser);
- if (flagValidate)
- {
- if (!Validate())
- return 2;
- if (flagValidateOnly)
- return 0;
- }
- if (flagGettext)
- OutputGettext();
- else
- CompileRes();
- return retCode;
- }
- return 1;
- }
- wxString XmlResApp::GeneratedNamespaceName() const
- {
- return aXRCWndClassData[0].GeneratedClassName() + "_NS";
- }
- void XmlResApp::ParseParams(const wxCmdLineParser& cmdline)
- {
- flagGettext = cmdline.Found("g");
- flagVerbose = cmdline.Found("v");
- flagCPP = cmdline.Found("c");
- flagPython = cmdline.Found("p");
- flagH = flagCPP && cmdline.Found("e");
- flagValidateOnly = cmdline.Found("validate-only");
- flagValidate = flagValidateOnly || cmdline.Found("validate");
- cmdline.Found("xrc-schema", &parSchemaFile);
- if (!cmdline.Found("o", &parOutput))
- {
- if (flagGettext)
- parOutput = wxEmptyString;
- else
- {
- if (flagCPP)
- parOutput = wxT("resource.cpp");
- else if (flagPython)
- parOutput = wxT("resource.py");
- else
- parOutput = wxT("resource.xrs");
- }
- }
- if (!parOutput.empty())
- {
- parOutput = wxFileName(parOutput).GetAbsolutePath();
- parOutputPath = wxPathOnly(parOutput);
- }
- if (!parOutputPath) parOutputPath = wxT(".");
- if (!cmdline.Found("n", &parFuncname))
- parFuncname = wxT("InitXmlResource");
- for (size_t i = 0; i < cmdline.GetParamCount(); i++)
- {
- #ifdef __WINDOWS__
- wxString fn = wxFindFirstFile(cmdline.GetParam(i), wxFILE);
- while (!fn.empty())
- {
- parFiles.Add(fn);
- fn = wxFindNextFile();
- }
- #else
- parFiles.Add(cmdline.GetParam(i));
- #endif
- }
- }
- void XmlResApp::CompileRes()
- {
- wxArrayString files = PrepareTempFiles();
- if (wxFileExists(parOutput))
- wxRemoveFile(parOutput);
- if (!retCode)
- {
- if (flagCPP) {
- MakePackageCPP(files);
- if (flagH)
- GenCPPHeader();
- }
- else if (flagPython)
- MakePackagePython(files);
- else
- MakePackageZIP(files);
- }
- DeleteTempFiles(files);
- }
- wxString XmlResApp::GetInternalFileName(const wxString& name, const wxArrayString& flist)
- {
- wxString name2 = name;
- name2.Replace(wxT(":"), wxT("_"));
- name2.Replace(wxT("/"), wxT("_"));
- name2.Replace(wxT("\"), wxT("_"));
- name2.Replace(wxT("*"), wxT("_"));
- name2.Replace(wxT("?"), wxT("_"));
- wxString s = wxFileNameFromPath(parOutput) + wxT("$") + name2;
- if (wxFileExists(s) && flist.Index(s) == wxNOT_FOUND)
- {
- for (int i = 0;; i++)
- {
- s.Printf(wxFileNameFromPath(parOutput) + wxT("$%03i-") + name2, i);
- if (!wxFileExists(s) || flist.Index(s) != wxNOT_FOUND)
- break;
- }
- }
- return s;
- }
- wxArrayString XmlResApp::PrepareTempFiles()
- {
- wxArrayString flist;
- for (size_t i = 0; i < parFiles.GetCount(); i++)
- {
- if (flagVerbose)
- wxPrintf(wxT("processing ") + parFiles[i] + wxT("...\n"));
- wxXmlDocument doc;
- if (!doc.Load(parFiles[i]))
- {
- wxLogError(wxT("Error parsing file ") + parFiles[i]);
- retCode = 1;
- continue;
- }
- wxString name, ext, path;
- wxFileName::SplitPath(parFiles[i], &path, &name, &ext);
- FindFilesInXML(doc.GetRoot(), flist, path);
- if (flagH)
- {
- wxXmlNode* node = (doc.GetRoot())->GetChildren();
- wxString classValue, nameValue;
- while (node) {
- if (node->GetName() == wxT("object")
- && node->GetAttribute(wxT("class"), &classValue)
- && node->GetAttribute(wxT("name"), &nameValue)) {
- aXRCWndClassData.Add(
- XRCWndClassData(nameValue, classValue, node)
- );
- }
- node = node->GetNext();
- }
- }
- wxString internalName = GetInternalFileName(parFiles[i], flist);
- doc.Save(parOutputPath + wxFILE_SEP_PATH + internalName);
- flist.Add(internalName);
- }
- return flist;
- }
- // Does 'node' contain filename information at all?
- static bool NodeContainsFilename(wxXmlNode* node)
- {
- const wxString name = node->GetName();
- // Any bitmaps (bitmap2 is used for disabled toolbar buttons):
- if (name == wxT("bitmap") || name == wxT("bitmap2"))
- return true;
- if (name == wxT("icon"))
- return true;
- // wxBitmapButton:
- wxXmlNode* parent = node->GetParent();
- if (parent != NULL &&
- parent->GetAttribute(wxT("class"), wxT("")) == wxT("wxBitmapButton") &&
- (name == wxT("focus") ||
- name == wxT("disabled") ||
- name == wxT("current") ||
- name == wxT("pressed") ||
- name == wxT("hover") ||
- name == wxT("selected")))
- return true;
- // wxBitmap or wxIcon toplevel resources:
- if (name == wxT("object"))
- {
- wxString klass = node->GetAttribute(wxT("class"), wxEmptyString);
- if (klass == wxT("wxBitmap") ||
- klass == wxT("wxIcon") ||
- klass == wxT("data"))
- return true;
- }
- // wxAnimationCtrl animations:
- if (name == wxS("animation"))
- return true;
- // URLs in wxHtmlWindow:
- if (name == wxT("url") &&
- parent != NULL &&
- parent->GetAttribute(wxT("class"), wxT("")) == wxT("wxHtmlWindow"))
- {
- // FIXME: this is wrong for e.g. http:// URLs
- return true;
- }
- return false;
- }
- // find all files mentioned in structure, e.g. <bitmap>filename</bitmap>
- void XmlResApp::FindFilesInXML(wxXmlNode* node, wxArrayString& flist, const wxString& inputPath)
- {
- // Is 'node' XML node element?
- if (node == NULL) return;
- if (node->GetType() != wxXML_ELEMENT_NODE) return;
- bool containsFilename = NodeContainsFilename(node);
- wxXmlNode* n = node->GetChildren();
- while (n)
- {
- if (containsFilename &&
- (n->GetType() == wxXML_TEXT_NODE ||
- n->GetType() == wxXML_CDATA_SECTION_NODE))
- {
- // At least <bitmap> content can include several semi-colon
- // separated paths corresponding to the different resolutions of
- // the bitmap, so check for this.
- wxArrayString internalNames;
- const wxArrayString paths = wxSplit(n->GetContent(), ';', '\0');
- for (size_t i = 0; i < paths.size(); ++i)
- {
- const wxString& path = paths[i];
- wxString fullname;
- if (wxIsAbsolutePath(path) || inputPath.empty())
- fullname = path;
- else
- fullname = inputPath + wxFILE_SEP_PATH + path;
- if (flagVerbose)
- wxPrintf(wxT("adding %s...\n"), fullname);
- wxFileInputStream sin(fullname);
- if (!sin)
- {
- // Note that the full name was already given in the error
- // message logged by wxFileInputStream itself, so don't repeat
- // it here.
- wxLogError("Failed to read file referenced by "%s" at %d",
- node->GetName(), node->GetLineNumber());
- retCode = 1;
- }
- else
- {
- wxString filename = GetInternalFileName(path, flist);
- // Copy the entire stream to the output file.
- wxFileOutputStream sout(parOutputPath + wxFILE_SEP_PATH + filename);
- if (sin.Read(sout).GetLastError() != wxSTREAM_EOF || !sout)
- {
- wxLogError("Failed to save "%s" referenced by "%s" at %d"
- " to a temporary file",
- fullname, node->GetName(), node->GetLineNumber());
- retCode = 1;
- }
- else
- {
- internalNames.push_back(filename);
- if (flist.Index(filename) == wxNOT_FOUND)
- flist.Add(filename);
- }
- }
- }
- n->SetContent(wxJoin(internalNames, ';', '\0'));
- }
- // subnodes:
- if (n->GetType() == wxXML_ELEMENT_NODE)
- FindFilesInXML(n, flist, inputPath);
- n = n->GetNext();
- }
- }
- void XmlResApp::DeleteTempFiles(const wxArrayString& flist)
- {
- for (size_t i = 0; i < flist.GetCount(); i++)
- wxRemoveFile(parOutputPath + wxFILE_SEP_PATH + flist[i]);
- }
- void XmlResApp::MakePackageZIP(const wxArrayString& flist)
- {
- wxString files;
- for (size_t i = 0; i < flist.GetCount(); i++)
- files += flist[i] + wxT(" ");
- files.RemoveLast();
- if (flagVerbose)
- wxPrintf(wxT("compressing ") + parOutput + wxT("...\n"));
- wxString cwd = wxGetCwd();
- wxSetWorkingDirectory(parOutputPath);
- int execres = wxExecute(wxT("zip -9 -j ") +
- wxString(flagVerbose ? wxT(""") : wxT("-q "")) +
- parOutput + wxT("" ") + files,
- wxEXEC_BLOCK);
- wxSetWorkingDirectory(cwd);
- if (execres == -1)
- {
- wxLogError(wxT("Unable to execute zip program. Make sure it is in the path."));
- wxLogError(wxT("You can download it at http://www.cdrom.com/pub/infozip/"));
- retCode = 1;
- return;
- }
- }
- static wxString FileToCppArray(wxString filename, int num)
- {
- wxString output;
- wxString tmp;
- wxString snum;
- wxFFile file(filename, wxT("rb"));
- wxFileOffset offset = file.Length();
- wxASSERT_MSG(offset >= 0, wxT("Invalid file length"));
- const size_t lng = wx_truncate_cast(size_t, offset);
- wxASSERT_MSG(static_cast<wxFileOffset>(lng) == offset,
- wxT("Huge file not supported"));
- snum.Printf(wxT("%i"), num);
- output.Printf(wxT("static size_t xml_res_size_") + snum + wxT(" = %lu;\n"),
- static_cast<unsigned long>(lng));
- output += wxT("static unsigned char xml_res_file_") + snum + wxT("[] = {\n");
- // we cannot use string literals because MSVC is dumb wannabe compiler
- // with arbitrary limitation to 2048 strings :(
- unsigned char* buffer = new unsigned char[lng];
- file.Read(buffer, lng);
- for (size_t i = 0, linelng = 0; i < lng; i++)
- {
- tmp.Printf(wxT("%i"), buffer[i]);
- if (i != 0) output << wxT(',');
- if (linelng > 70)
- {
- linelng = 0;
- output << wxT("\n");
- }
- output << tmp;
- linelng += tmp.Length() + 1;
- }
- delete[] buffer;
- output += wxT("};\n\n");
- return output;
- }
- void XmlResApp::MakePackageCPP(const wxArrayString& flist) {
- wxFFile file(parOutput, wxT("wt"));
- unsigned i;
- if (flagVerbose)
- wxPrintf(wxT("creating C++ source file ") + parOutput + wxT("...\n"));
- file.Write(""
- "//\n"
- "// This file was automatically generated by wxrc, do not edit by hand.\n"
- "//\n\n"
- "#include <wx/wxprec.h>\n"
- "\n"
- "#include <wx/filesys.h>\n"
- "#include <wx/fs_mem.h>\n"
- "#include <wx/xrc/xmlres.h>\n"
- "#include <wx/xrc/xh_all.h>\n"
- "\n"
- "#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805\n"
- " #define XRC_ADD_FILE(name, data, size, mime) \\\n"
- " wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime)\n"
- "#else\n"
- " #define XRC_ADD_FILE(name, data, size, mime) \\\n"
- " wxMemoryFSHandler::AddFile(name, data, size)\n"
- "#endif\n"
- "\n");
- // 获取命名空间名称(与头文件一致)
- wxString namespaceName;
- if (aXRCWndClassData.GetCount() > 0) {
- namespaceName = GeneratedNamespaceName();
- }
- // 开始命名空间
- file.Write("\nnamespace " + namespaceName + " {\n\n");
- // 将资源数组定义放在命名空间内
- for (i = 0; i < flist.GetCount(); i++) {
- file.Write(FileToCppArray(parOutputPath + wxFILE_SEP_PATH + flist[i], i));
- }
- file.Write("void " + parFuncname + "()\n"
- "{\n"
- "\n"
- " // Check for memory FS. If not present, load the handler:\n"
- " {\n"
- " wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one"));\n"
- " wxFileSystem fsys;\n"
- " wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));\n"
- " wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));\n"
- " if (f) delete f;\n"
- " else wxFileSystem::AddHandler(new wxMemoryFSHandler);\n"
- " }\n"
- "\n");
- for (i = 0; i < flist.GetCount(); i++) {
- wxString s;
- wxString mime;
- wxString ext = wxFileName(flist[i]).GetExt();
- if (ext.Lower() == wxT("xrc"))
- mime = wxT("text/xml");
- #if wxUSE_MIMETYPE
- else {
- wxFileType* ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
- if (ft) {
- ft->GetMimeType(&mime);
- delete ft;
- }
- }
- #endif // wxUSE_MIMETYPE
- s.Printf(" XRC_ADD_FILE(wxT("XRC_resource/" + flist[i] +
- ""), xml_res_file_%u, xml_res_size_%u, wxT("%s"));\n",
- i, i, mime.c_str());
- file.Write(s);
- }
- for (i = 0; i < parFiles.GetCount(); i++) {
- file.Write(" wxXmlResource::Get()->Load(wxT("memory:XRC_resource/" +
- GetInternalFileName(parFiles[i], flist) + ""));\n");
- }
- file.Write("}\n\n");
- // 结束命名空间
- file.Write("} // namespace " + namespaceName + "\n");
- }
- void XmlResApp::GenCPPHeader()
- {
- // Generate the output header in the same directory as the source file.
- wxFileName headerName(parOutput);
- headerName.SetExt("h");
- wxFFile file(headerName.GetFullPath(), wxT("wt"));
- file.Write(
- "//\n"
- "// This file was automatically generated by wxrc, do not edit by hand.\n"
- "//\n\n"
- "#ifndef __" + headerName.GetName() + "_h__\n"
- "#define __" + headerName.GetName() + "_h__\n"
- "#include <wx/wxprec.h>\n"
- "\n"
- "#include <wx/filesys.h>\n"
- "#include <wx/fs_mem.h>\n"
- "#include <wx/xrc/xmlres.h>\n"
- "#include <wx/xrc/xh_all.h>\n"
- );
- if (aXRCWndClassData.GetCount() > 0) {
- wxString namespaceName = GeneratedNamespaceName();
- file.Write("\nnamespace " + namespaceName + " {\n");
- file.Write("void " + parFuncname + "();\n");
- file.Write("}\n");
- }
- for (size_t i = 0; i < aXRCWndClassData.GetCount(); ++i) {
- aXRCWndClassData.Item(i).GenerateHeaderCode(file);
- }
- // 修改后的片段
- file.Write("#endif\n");
- }
- static wxString FileToPythonArray(wxString filename, int num)
- {
- wxString output;
- wxString tmp;
- wxString snum;
- wxFFile file(filename, wxT("rb"));
- wxFileOffset offset = file.Length();
- wxASSERT_MSG(offset >= 0, wxT("Invalid file length"));
- const size_t lng = wx_truncate_cast(size_t, offset);
- wxASSERT_MSG(static_cast<wxFileOffset>(lng) == offset,
- wxT("Huge file not supported"));
- snum.Printf(wxT("%i"), num);
- output = " xml_res_file_" + snum + " = '''\\\n";
- unsigned char* buffer = new unsigned char[lng];
- file.Read(buffer, lng);
- for (size_t i = 0, linelng = 0; i < lng; i++)
- {
- unsigned char c = buffer[i];
- if (c == '\n')
- {
- tmp = (wxChar)c;
- linelng = 0;
- }
- else if (c < 32 || c > 127 || c == '\'')
- tmp.Printf(wxT("\\x%02x"), c);
- else if (c == '\\')
- tmp = wxT("\\\");
- else
- tmp = (wxChar)c;
- if (linelng > 70)
- {
- linelng = 0;
- output << wxT("\\\n");
- }
- output << tmp;
- linelng += tmp.Length();
- }
- delete[] buffer;
- output += wxT("'''\n\n");
- return output;
- }
- void XmlResApp::MakePackagePython(const wxArrayString& flist)
- {
- wxFFile file(parOutput, wxT("wt"));
- unsigned i;
- if (flagVerbose)
- wxPrintf(wxT("creating Python source file ") + parOutput + wxT("...\n"));
- file.Write(
- "#\n"
- "# This file was automatically generated by wxrc, do not edit by hand.\n"
- "#\n\n"
- "import wx\n"
- "import wx.xrc\n\n"
- );
- file.Write("def " + parFuncname + "():\n");
- for (i = 0; i < flist.GetCount(); i++)
- file.Write(
- FileToPythonArray(parOutputPath + wxFILE_SEP_PATH + flist[i], i));
- file.Write(
- " # check if the memory filesystem handler has been loaded yet, and load it if not\n"
- " wx.MemoryFSHandler.AddFile('XRC_resource/dummy_file', 'dummy value')\n"
- " fsys = wx.FileSystem()\n"
- " f = fsys.OpenFile('memory:XRC_resource/dummy_file')\n"
- " wx.MemoryFSHandler.RemoveFile('XRC_resource/dummy_file')\n"
- " if f is not None:\n"
- " f.Destroy()\n"
- " else:\n"
- " wx.FileSystem.AddHandler(wx.MemoryFSHandler())\n"
- "\n"
- " # load all the strings as memory files and load into XmlRes\n"
- );
- for (i = 0; i < flist.GetCount(); i++)
- {
- wxString s;
- s.Printf(" wx.MemoryFSHandler.AddFile('XRC_resource/" + flist[i] +
- "', xml_res_file_%u)\n", i);
- file.Write(s);
- }
- for (i = 0; i < parFiles.GetCount(); i++)
- {
- file.Write(" wx.xrc.XmlResource.Get().Load('memory:XRC_resource/" +
- GetInternalFileName(parFiles[i], flist) + "')\n");
- }
- file.Write("\n");
- }
- void XmlResApp::OutputGettext()
- {
- ExtractedStrings str = FindStrings();
- wxFFile fout;
- if (parOutput.empty())
- fout.Attach(stdout);
- else
- fout.Open(parOutput, wxT("wt"));
- for (ExtractedStrings::const_iterator i = str.begin(); i != str.end(); ++i)
- {
- const wxFileName filename(i->filename);
- wxString s;
- s.Printf("#line %d "%s"\n",
- i->lineNo, filename.GetFullPath(wxPATH_UNIX));
- fout.Write(s);
- fout.Write("_("" + i->str + "");\n");
- }
- if (!parOutput) fout.Detach();
- }
- ExtractedStrings XmlResApp::FindStrings()
- {
- ExtractedStrings arr, a2;
- for (size_t i = 0; i < parFiles.GetCount(); i++)
- {
- if (flagVerbose)
- wxPrintf(wxT("processing ") + parFiles[i] + wxT("...\n"));
- wxXmlDocument doc;
- if (!doc.Load(parFiles[i]))
- {
- wxLogError(wxT("Error parsing file ") + parFiles[i]);
- retCode = 1;
- continue;
- }
- a2 = FindStrings(parFiles[i], doc.GetRoot());
- WX_APPEND_ARRAY(arr, a2);
- }
- return arr;
- }
- static wxString ConvertText(const wxString& str)
- {
- wxString str2;
- const wxChar* dt;
- for (dt = str.c_str(); *dt; dt++)
- {
- if (*dt == wxT('_'))
- {
- if (*(dt + 1) == 0)
- str2 << wxT('_');
- else if (*(++dt) == wxT('_'))
- str2 << wxT('_');
- else
- str2 << wxT('&') << *dt;
- }
- else
- {
- switch (*dt)
- {
- case wxT('\n'): str2 << wxT("\\n"); break;
- case wxT('\t'): str2 << wxT("\\t"); break;
- case wxT('\r'): str2 << wxT("\\r"); break;
- case wxT('\\'): if ((*(dt + 1) != 'n') &&
- (*(dt + 1) != 't') &&
- (*(dt + 1) != 'r'))
- str2 << wxT("\\\");
- else
- str2 << wxT("\");
- break;
- case wxT('"'): str2 << wxT("\\""); break;
- default: str2 << *dt; break;
- }
- }
- }
- return str2;
- }
- enum ContentsKind
- {
- Contents_NotTrans, // Not a translatable text at all.
- Contents_TransOnly, // Translatable but not escaped text.
- Contents_Text // Text, i.e. both translatable and escaped.
- };
- // Check if the given node contains translatable text and, if it does, whether
- // it's escaped (i.e. parsed using GetText()) or not.
- ContentsKind
- GetNodeContentsKind(wxXmlNode& node, const wxString& contents)
- {
- if (node.GetName() == wxT("label") ||
- (node.GetName() == wxT("value") && !contents.IsNumber()) ||
- node.GetName() == wxT("help") ||
- node.GetName() == wxT("hint") ||
- node.GetName() == wxT("longhelp") ||
- node.GetName() == wxT("tooltip") ||
- node.GetName() == wxT("htmlcode") ||
- node.GetName() == wxT("title") ||
- node.GetName() == wxT("message") ||
- node.GetName() == wxT("note") ||
- node.GetName() == wxT("defaultdirectory") ||
- node.GetName() == wxT("defaultfilename") ||
- node.GetName() == wxT("defaultfolder") ||
- node.GetName() == wxT("filter") ||
- node.GetName() == wxT("caption"))
- {
- return Contents_Text;
- }
- // This one is special: it is translated in XRC, but its contents is not
- // escaped, except for the special case of wxRadioBox when it can be, if
- // "label" attribute is supplied.
- if (node.GetName() == wxT("item"))
- {
- return node.GetAttribute(wxT("label"), wxT("0")) == wxT("1")
- ? Contents_Text
- : Contents_TransOnly;
- }
- return Contents_NotTrans;
- }
- ExtractedStrings
- XmlResApp::FindStrings(const wxString& filename, wxXmlNode* node)
- {
- ExtractedStrings arr;
- wxXmlNode* n = node;
- if (n == NULL) return arr;
- n = n->GetChildren();
- while (n)
- {
- if ((node->GetType() == wxXML_ELEMENT_NODE) &&
- // parent is an element, i.e. has subnodes...
- (n->GetType() == wxXML_TEXT_NODE ||
- n->GetType() == wxXML_CDATA_SECTION_NODE))
- // ...it is textnode...
- {
- wxString s = n->GetContent();
- switch (GetNodeContentsKind(*node, s))
- {
- case Contents_NotTrans:
- break;
- case Contents_Text:
- s = ConvertText(s);
- wxFALLTHROUGH;
- case Contents_TransOnly:
- if (!flagGettext ||
- node->GetAttribute(wxT("translate"), wxT("1")) != wxT("0"))
- {
- arr.push_back(ExtractedString(s, filename, n->GetLineNumber()));
- }
- break;
- }
- }
- // subnodes:
- if (n->GetType() == wxXML_ELEMENT_NODE)
- {
- ExtractedStrings a2 = FindStrings(filename, n);
- WX_APPEND_ARRAY(arr, a2);
- }
- n = n->GetNext();
- }
- return arr;
- }
- bool XmlResApp::Validate()
- {
- if (flagVerbose)
- wxPuts("validating XRC files...");
- wxString schemaURI;
- if (!parSchemaFile.empty())
- {
- schemaURI = parSchemaFile;
- }
- else
- {
- schemaURI = "http://www.wxwidgets.org/wxxrc";
- // Normally, we'd use an OASIS XML catalog to map the URI to a local copy,
- // but Jing's catalog support (-C catalogFile) requires additional
- // dependency, resolver.jar, that is not commonly installed alongside Jing
- // by systems that package Jing. So do the (trivial) mapping manually here:
- wxString wxWinRoot;
- if (wxGetEnv("WXWIN", &wxWinRoot))
- {
- wxString schemaFile(wxWinRoot + "/misc/schema/xrc_schema.rnc");
- if (wxFileExists(schemaFile))
- schemaURI = schemaFile;
- }
- }
- wxString cmdline = wxString::Format("jing -c "%s"", schemaURI);
- for (size_t i = 0; i < parFiles.GetCount(); i++)
- cmdline << wxString::Format(" "%s"", parFiles[i]);
- int res = wxExecute(cmdline, wxEXEC_BLOCK);
- if (res == -1)
- {
- wxLogError("Running RELAX NG validator failed.");
- wxLogError("Please install Jing (http://www.thaiopensource.com/relaxng/jing.html).");
- wxLogError("See https://github.com/wxWidgets/wxWidgets/blob/master/misc/schema/README for more information.");
- return false;
- }
- if (flagVerbose)
- {
- if (res == 0)
- wxPuts("XRC validation passed without errors.");
- else
- wxPuts("XRC validation failed, there are errors.");
- }
- return res == 0;
- }
4. 在项目中使用 wx 窗体,需要一些准备;
4.1 添加一个 GlobalWxApp.h 文件,代码如下:
 - #pragma once
- #include <wx/wx.h>
- #include <acedads.h>
- #include <singleInstance.h>
- #include <wx/msw/app.h>
- #include <wx/xrc/xmlres.h>
- #include <wx/event.h>
- // 精简版全局应用管理器
- class GlobalWxApp : public wxApp, public SingleInstance<GlobalWxApp> {
- private:
- HWND m_hwndAcad; // 存储AutoCAD主窗口句柄
- public:
- GlobalWxApp() {
- // 初始化设置cad 窗口句柄
- m_hwndAcad = adsw_acadMainWnd();
- //初始化xrc资源预设
- wxXmlResource::Get()->InitAllHandlers();
- }
- bool OnInit() override {
- if (!wxApp::OnInit())
- return false;
- // 设置wxWidgets使用的父窗口
- if (m_hwndAcad) {
- // 获取当前的顶级窗口
- wxWindow* topWindow = GetTopWindow();
- if (topWindow) {
- // 设置AutoCAD为父窗口
- ::SetParent((HWND)topWindow->GetHWND(), m_hwndAcad);
- }
- }
- return true;
- }
- //显示任意窗口
- void Show(wxWindow* window) {
- window->Show();
- window->Raise();
- }
- };
- class WxConnect {
- public:
- template <typename TControl, typename TEvent>
- static void Connect(TControl* control, TEvent eventType, void (*func)()) {
- control->Bind(eventType, [func](wxEvent&) { func(); });
- }
- template <typename TControl, typename TEvent, typename TEventArg>
- static void Connect(TControl* control, TEvent eventType, void (*func)(TEventArg&)) {
- control->Bind(eventType, [func](wxEvent& e) { func(static_cast<TEventArg&>(e)); });
- }
- };
4.2 xrc 文件如下:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|