.H
// CadMenuParserDlg.h : 头文件
//
#pragma once
// CCadMenuParserDlg 对话框
class CCadMenuParserDlg : public CDialog
{
// 构造
public:
CCadMenuParserDlg(CWnd* pParent = NULL);// 标准构造函数
// 对话框数据
enum { IDD = IDD_CADMENUPARSER_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持
void FindFiles(CTreeCtrl* m_Tree,HTREEITEM root,HTREEITEM parent,CString strPath,int deep);
void AddChildItems(CTreeCtrl* m_Tree,POSITION& position,HTREEITEM parent);
void AddRootChild(CTreeCtrl* m_Tree,POSITION position,HTREEITEM root);
bool MenuItemHasChild(const CString& ItemStr);
bool ContainSubStr(const CString& str,const CString& subStr);
void ExtractMenuCtn(CString& menuItemStr);
void FiltNodesHasChild(POSITION& position);
//=============
void GetParentItemStr(CTreeCtrl* tree,HTREEITEM item,CString& path);
CString m_buffer;
CStringList m_nodeLst;
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedBtnfiledlg();
afx_msg void OnBnClickedBtndirdlg();
afx_msg void OnTvnSelchangedTreenodes(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnNMDblclkTreenodes(NMHDR *pNMHDR, LRESULT *pResult);
};
.CPP
// CadMenuParserDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "CadMenuParser.h"
#include "CadMenuParserDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CCadMenuParserDlg 对话框
CCadMenuParserDlg::CCadMenuParserDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCadMenuParserDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCadMenuParserDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CCadMenuParserDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BTNFILEDLG, &CCadMenuParserDlg::OnBnClickedBtnfiledlg)
ON_BN_CLICKED(IDC_BTNDIRDLG, &CCadMenuParserDlg::OnBnClickedBtndirdlg)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREENODES, &CCadMenuParserDlg::OnTvnSelchangedTreenodes)
ON_NOTIFY(NM_DBLCLK, IDC_TREENODES, &CCadMenuParserDlg::OnNMDblclkTreenodes)
END_MESSAGE_MAP()
// CCadMenuParserDlg 消息处理程序
BOOL CCadMenuParserDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE);// 设置大图标
SetIcon(m_hIcon, FALSE);// 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CCadMenuParserDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CCadMenuParserDlg::OnQueryDragIcon()
{
return static_cast(m_hIcon);
}
////解析CAD文件================================================
bool CCadMenuParserDlg::ContainSubStr(const CString& str,const CString& subStr){
return str.Find(subStr) != -1;
}
void CCadMenuParserDlg::ExtractMenuCtn(CString& menuItemStr){
CString s;
bool save = false;
for(int i = 0;i < menuItemStr.GetLength();i ++){
wchar_t chr= menuItemStr.GetAt(i);
if(']' == chr){
menuItemStr = s;
return;
}
if('[' == chr){
save = true;
continue;
}
if(save){
s.AppendChar(menuItemStr.GetAt(i));
}
}
}
////获得子节点
void CCadMenuParserDlg::AddChildItems(CTreeCtrl* m_Tree,POSITION& position,HTREEITEM parent){
CString strNode;
while (position != NULL)
{
strNode = m_nodeLst.GetNext(position);
HTREEITEM current = m_Tree->InsertItem(strNode,NULL,NULL,parent);
if(this->MenuItemHasChild(strNode)){
//POSITION p = position;
this->AddChildItems(m_Tree,position,current);
}
if(this->ContainSubStr(strNode,_T("<-"))){
return;
}
}
}
////获得根节点的子节点
void CCadMenuParserDlg::AddRootChild(CTreeCtrl* m_Tree,POSITION position,HTREEITEM root){
//m_nodeLst.GetNext(position);
CString strNode;
while (position != NULL)
{
strNode = m_nodeLst.GetNext(position);
if(this->ContainSubStr(strNode,_T("***POP"))){
return;
}
HTREEITEM current = m_Tree->InsertItem(strNode,NULL,NULL,root);
if(MenuItemHasChild(strNode)){
this->AddChildItems(m_Tree,position,current);
}
}
}
////菜单节点是否包含子节点
bool CCadMenuParserDlg::MenuItemHasChild(const CString& itemStr){
return itemStr.Find(_T("->")) != -1;
}
void CCadMenuParserDlg::OnBnClickedBtnfiledlg()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE, NULL, NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
NULL);
if(dlg.DoModal() == IDOK)
{
////打开文件
CString szFilename = dlg.GetPathName();
CFile f;
f.Open(szFilename,CFile::modeReadWrite);
////读入缓存
char* buf = new char[f.GetLength() + 1];
buf[f.GetLength()] = 0;
f.Read(buf,f.GetLength());
f.Close();
m_buffer = CString(buf);
////读入LIST
CString str;
bool read = false;
for(int i = 0;i < m_buffer.GetLength();i++){
if(m_buffer.GetAt(i) == '\n'){
if(this->ContainSubStr(str,_T("***POP500"))){
break;
}
if(this->ContainSubStr(str,_T("***POP"))){
m_nodeLst.AddTail(str);
str.Empty();
read = true;
continue;
}
if(read && this->ContainSubStr(str,_T("ID_")) ){
////过滤
this->ExtractMenuCtn(str);
m_nodeLst.AddTail(str);
str.Empty();
continue;
}
str.Empty();
}
str.AppendChar(m_buffer.GetAt(i));
}
CTreeCtrl* m_Tree = (CTreeCtrl*)GetDlgItem(IDC_TREENODES);
m_Tree->DeleteAllItems();
////设置样式
m_Tree->ModifyStyle(NULL,TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT);
//HTREEITEM root = m_Tree->InsertItem(szPath,NULL,NULL);///root就是节点的标题
POSITION rPos;
rPos = m_nodeLst.GetHeadPosition();
CString strNode;
while (rPos != NULL)
{
strNode = m_nodeLst.GetNext(rPos);
if(this->ContainSubStr(strNode,_T("***POP"))){
strNode = m_nodeLst.GetNext(rPos);
HTREEITEM root = m_Tree->InsertItem(strNode,NULL,NULL);////插入root
this->AddRootChild(m_Tree,rPos,root);
}
}
}
}
////遍历目录===============================================================
void CCadMenuParserDlg::FindFiles(CTreeCtrl* m_Tree,HTREEITEM root,HTREEITEM parent,CString strPath,int deep){
////最多找10层节点
if(deep > 10){
return;
}
CString strWildcard(strPath);
strWildcard += _T("\\*.*");
CFileFind ff;
BOOL bFind = ff.FindFile(strWildcard);
while(bFind)
{
bFind = ff.FindNextFile();
if (ff.IsDots() || ff.IsSystem() || ff.IsHidden())
continue;
if (ff.IsDirectory())
{
CString dir = ff.GetFilePath();
HTREEITEM currentNode;
if(parent==NULL){
currentNode = m_Tree->InsertItem(dir,NULL,NULL,root);
}
else{
currentNode = m_Tree->InsertItem(dir,NULL,NULL,parent);
}
this->FindFiles(m_Tree,root,currentNode,dir,++deep);
}
else
{
CString strFileName = ff.GetFilePath();
if(parent==NULL){
m_Tree->InsertItem(strFileName,NULL,NULL,root);
}
else{
m_Tree->InsertItem(strFileName,NULL,NULL,parent);
}
}
}
}
void CCadMenuParserDlg::OnBnClickedBtndirdlg()
{
CString strP =_T("选择目录");
int length = 1024;
LPWSTR szPath = strP.GetBuffer(1024);
// do something with the string that pwsz points to.
strP.ReleaseBuffer();
CString str;
BROWSEINFO bi;
bi.hwndOwner = m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = szPath;
bi.lpszTitle = _T("请选择要遍历的目录:");
bi.ulFlags = 0;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
//弹出选择目录对话框
LPITEMIDLIST lp = SHBrowseForFolder(&bi);
if(lp && SHGetPathFromIDList(lp,szPath))
{
CTreeCtrl* m_Tree = (CTreeCtrl*)GetDlgItem(IDC_TREENODES);
m_Tree->DeleteAllItems();
////设置样式
m_Tree->ModifyStyle(NULL,TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT);
HTREEITEM root = m_Tree->InsertItem(szPath,NULL,NULL);///root就是节点的标题
this->FindFiles(m_Tree,root,NULL,szPath,0);
}
else {
AfxMessageBox(_T("无效的目录,请重新选择"));
}
// TODO: 在此添加控件通知处理程序代码
}
void CCadMenuParserDlg::OnTvnSelchangedTreenodes(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR);
CTreeCtrl* m_Tree = (CTreeCtrl*)GetDlgItem(IDC_TREENODES);
HTREEITEM item = m_Tree->GetSelectedItem();
CString itemTxt = m_Tree->GetItemText(item);
CStatic* lbl = (CStatic*)GetDlgItem(IDC_LBLNODETEXT);
lbl->SetWindowText(itemTxt);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
}
//=======================================================
void CCadMenuParserDlg::GetParentItemStr(CTreeCtrl* tree,HTREEITEM item,CString& path){
}
////如果选择的是文本,读出这个文件
void CCadMenuParserDlg::OnNMDblclkTreenodes(NMHDR *pNMHDR, LRESULT *pResult)
{
CTreeCtrl* m_Tree = (CTreeCtrl*)GetDlgItem(IDC_TREENODES);
CString path;
HTREEITEM item = m_Tree->GetSelectedItem();
path = m_Tree->GetItemText(item);
if(this->ContainSubStr(path,_T(".txt"))){
CFile f;
f.Open(path,CFile::modeReadWrite);
char* buf = new char[f.GetLength() + 1];
buf[f.GetLength()] = 0;
f.Read(buf,f.GetLength());
f.Close();
CString s(buf);
CEdit* txt = (CEdit*)GetDlgItem(IDC_TXTDOC);
txt->SetWindowText(s);
}
else{
AfxMessageBox(_T("只有选择TXT文件时,才能通过双击打开"));
}
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
}