工具名称
自定义工作台
工具说明
*通过配置config.txt,自动生成按钮,点击执行对应的内容
*目前支持,打开文件夹,打开文件,执行cmd命令,打开网址
配置文件解析
*配置一行参数是一个按钮
*三个参数:名字,类型,"内容"
*名字是按钮显示的内容,类型则表示需要执行的规则,内容需要用""包裹
*每一行只能执行一个命令,如果需要复杂的命令,可以写成bat,打开bat进行执行
*如果有特殊的情况,可以使用多个工作台,执行不同的内容
*每行6个按钮,最大1000个按钮
*例子:打开ReadMe,OPEN_FILE,"ReadMe.txt"
打开bat,OPEN_FILE,"bat\导出log.bat"
打开网址,URL,"https://www.tttt.com/"
执行cmd命令,EXECUTE_CMD,"adb root"
打开文件夹,OPEN_FOLDER,"D:\project\"
代码
cpp
cpp
// WorkBenchesDlg.cpp : implementation file
//
#include "stdafx.h"
#include "WorkBenches.h"
#include "WorkBenchesDlg.h"
#include "DlgProxy.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CWorkBenchesDlg dialog
IMPLEMENT_DYNAMIC(CWorkBenchesDlg, CDialog);
CWorkBenchesDlg::CWorkBenchesDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWorkBenchesDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CWorkBenchesDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pAutoProxy = NULL;
m_pButtons = NULL;
m_nButtonCount = 0;
m_ButtonRect.SetRect(20, 20, 120, 50); // 第一个按钮的位置和大小
}
CWorkBenchesDlg::~CWorkBenchesDlg()
{
// If there is an automation proxy for this dialog, set
// its back pointer to this dialog to NULL, so it knows
// the dialog has been deleted.
if (m_pAutoProxy != NULL)
m_pAutoProxy->m_pDialog = NULL;
}
void CWorkBenchesDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWorkBenchesDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
// 动态按钮的ID范围
#define IDC_FIRST_DYNAMIC_BUTTON 1000
BEGIN_MESSAGE_MAP(CWorkBenchesDlg, CDialog)
//{{AFX_MSG_MAP(CWorkBenchesDlg)
ON_WM_CLOSE()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
// 动态按钮的消息映射
ON_CONTROL_RANGE(BN_CLICKED, IDC_FIRST_DYNAMIC_BUTTON,
IDC_FIRST_DYNAMIC_BUTTON + 1000,
OnDynamicButtonClicked)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWorkBenchesDlg message handlers
BOOL CWorkBenchesDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
Init();
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CWorkBenchesDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
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;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CWorkBenchesDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
// Automation servers should not exit when a user closes the UI
// if a controller still holds on to one of its objects. These
// message handlers make sure that if the proxy is still in use,
// then the UI is hidden but the dialog remains around if it
// is dismissed.
void CWorkBenchesDlg::OnClose()
{
if (CanExit())
CDialog::OnClose();
}
void CWorkBenchesDlg::OnOK()
{
if (CanExit())
CDialog::OnOK();
}
void CWorkBenchesDlg::OnCancel()
{
if (CanExit())
CDialog::OnCancel();
}
BOOL CWorkBenchesDlg::CanExit()
{
// If the proxy object is still around, then the automation
// controller is still holding on to this application. Leave
// the dialog around, but hide its UI.
if (m_pAutoProxy != NULL)
{
ShowWindow(SW_HIDE);
return FALSE;
}
return TRUE;
}
void CWorkBenchesDlg::Init(){
// 读取按钮配置文件
CString strFileName = _T("config.txt"); // 按钮配置文件
ReadButtonFile(strFileName);
// 创建动态按钮
CreateDynamicButtons();
}
void CWorkBenchesDlg::ReadButtonFile(LPCTSTR lpszFileName)
{
// 清空现有数据
m_ButtonTexts.RemoveAll();
m_ButtonActions.RemoveAll();
m_ButtonActionsParam.RemoveAll();
CStdioFile file;
// if (!file.Open(lpszFileName, CFile::modeRead))
// {
// MessageBox(_T("无法打开按钮配置文件!"), _T("错误"), MB_OK | MB_ICONERROR);
// return;
// }
CFileException ex;
// 尝试打开文件
if (!file.Open(lpszFileName, CFile::modeRead | CFile::typeText, &ex))
{
CString strError;
CString strCause;
// 根据错误代码显示具体原因
switch(ex.m_cause)
{
case CFileException::fileNotFound:
strCause = _T("文件不存在");
break;
case CFileException::badPath:
strCause = _T("路径无效或不存在");
break;
case CFileException::accessDenied:
strCause = _T("访问被拒绝(无权限或文件被锁定)");
break;
case CFileException::sharingViolation:
strCause = _T("共享冲突(文件被其他程序使用)");
break;
case CFileException::diskFull:
strCause = _T("磁盘已满");
break;
case CFileException::badSeek:
strCause = _T("文件指针错误");
break;
case CFileException::hardIO:
strCause = _T("硬件I/O错误");
break;
case CFileException::directoryFull:
strCause = _T("目录已满");
break;
case CFileException::tooManyOpenFiles:
strCause = _T("打开文件过多");
break;
default:
strCause.Format(_T("未知错误 (代码: %d)"), ex.m_cause);
break;
}
// 显示详细错误信息
strError.Format(_T("无法打开文件: %s\n\n")
_T("错误原因: %s\n")
_T("操作系统错误代码: %d"),
lpszFileName, strCause, ex.m_lOsError);
MessageBox(strError, _T("文件打开失败"), MB_OK | MB_ICONERROR);
return;
}
CString strLine;
while (file.ReadString(strLine))
{
// 跳过空行
if (strLine.IsEmpty()) continue;
// 查找分隔符
int nPos = strLine.Find(_T(','));
if (nPos != -1)
{
// 找第二个逗号
int nPos2 = strLine.Find(_T(','), nPos + 1);
if (nPos2 != -1)
{
CString strText = strLine.Left(nPos);
CString strAction = strLine.Mid(nPos + 1, nPos2 - nPos - 1); // "OPEN_FILE"
CString strParam = strLine.Mid(nPos2 + 1); // "d:\\123.txt"
m_ButtonTexts.Add(strText);
m_ButtonActions.Add(strAction);
m_ButtonActionsParam.Add(strParam);
}
}
else
{
// 如果只有按钮文本
m_ButtonTexts.Add(strLine);
m_ButtonActions.Add(_T("")); // 空动作
}
}
file.Close();
m_nButtonCount = m_ButtonTexts.GetSize();
}
void CWorkBenchesDlg::CreateDynamicButtons()
{
// 删除已有的动态按钮
if (m_pButtons)
{
for (int i = 0; i < m_nButtonCount; i++)
{
if (m_pButtons[i].GetSafeHwnd())
m_pButtons[i].DestroyWindow();
}
delete[] m_pButtons;
m_pButtons = NULL;
}
if (m_nButtonCount == 0) return;
// 创建新的按钮数组
m_pButtons = new CButton[m_nButtonCount];
// 按钮布局参数
int nButtonWidth = 100;
int nButtonHeight = 30;
int nHorizontalSpacing = 10;
int nVerticalSpacing = 10;
int nButtonsPerRow = 6; // 每行3个按钮
CRect rect;
GetClientRect(&rect);
for (int i = 0; i < m_nButtonCount; i++)
{
// 计算按钮位置
int nRow = i / nButtonsPerRow;
int nCol = i % nButtonsPerRow;
int nX = 20 + (nButtonWidth + nHorizontalSpacing) * nCol;
int nY = 20 + (nButtonHeight + nVerticalSpacing) * nRow;
CRect btnRect(nX, nY, nX + nButtonWidth, nY + nButtonHeight);
// 创建按钮
m_pButtons[i].Create(m_ButtonTexts[i],
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
btnRect,
this,
IDC_FIRST_DYNAMIC_BUTTON + i);
// 设置按钮字体
CFont* pFont = GetFont();
if (pFont)
m_pButtons[i].SetFont(pFont);
}
// 调整对话框大小以适应所有按钮
int nTotalRows = (m_nButtonCount + nButtonsPerRow - 1) / nButtonsPerRow;
int nRequiredHeight = 40 + (nButtonHeight + nVerticalSpacing) * nTotalRows;
if (nRequiredHeight > rect.Height())
{
CRect wndRect;
GetWindowRect(&wndRect);
SetWindowPos(NULL, 0, 0,
wndRect.Width(),
wndRect.Height() + (nRequiredHeight - rect.Height()),
SWP_NOMOVE | SWP_NOZORDER);
}
}
void CWorkBenchesDlg::OnDynamicButtonClicked(UINT nID)
{
int nIndex = nID - IDC_FIRST_DYNAMIC_BUTTON;
if (nIndex >= 0 && nIndex < m_nButtonCount)
{
CString strMessage;
strMessage.Format(_T("点击了按钮: %s\n执行动作: %s\n动作内容: %s"),
m_ButtonTexts[nIndex],
m_ButtonActions[nIndex],
m_ButtonActionsParam[nIndex]
);
// 显示信息
// MessageBox(strMessage, _T("按钮点击"), MB_OK | MB_ICONINFORMATION);
// 执行对应的动作
ExecuteAction(nIndex);
}
}
void CWorkBenchesDlg::ExecuteAction( int nIndex)
{
CString strAction;
CString strParam;
if (nIndex >= 0 && nIndex < m_nButtonCount)
{
strAction= m_ButtonActions[nIndex];
strParam= m_ButtonActionsParam[nIndex];
}
if (strAction.IsEmpty()) return;
if (strParam.IsEmpty()) return;
// 根据不同的动作执行不同的操作
// 这里只是示例,你可以根据实际需求扩展
if (strAction.CompareNoCase(_T("OPEN_FOLDER")) == 0)
{
// 使用ShellExecute函数打开文件夹
ShellExecute(NULL, _T("open"), strParam, NULL, NULL, SW_SHOWNORMAL);
}
else if (strAction.CompareNoCase(_T("OPEN_FILE")) == 0)
{
ShellExecute(NULL, _T("open"), strParam, NULL, NULL, SW_SHOWNORMAL);
}
else if (strAction.CompareNoCase(_T("EXECUTE_CMD")) == 0)
{
system(strParam);
}
else if (strAction.CompareNoCase(_T("URL")) == 0)
{
ShellExecute(NULL, _T("open"), strParam, NULL, NULL, SW_SHOWNORMAL);
}
else if (strAction.CompareNoCase(_T("EXIT")) == 0)
{
}
}
header
cpp
// WorkBenchesDlg.h : header file
//
#if !defined(AFX_WORKBENCHESDLG_H__B4B7DEE0_3AE7_418A_A81B_F9DB41C5FB25__INCLUDED_)
#define AFX_WORKBENCHESDLG_H__B4B7DEE0_3AE7_418A_A81B_F9DB41C5FB25__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CWorkBenchesDlgAutoProxy;
/////////////////////////////////////////////////////////////////////////////
// CWorkBenchesDlg dialog
class CWorkBenchesDlg : public CDialog
{
DECLARE_DYNAMIC(CWorkBenchesDlg);
friend class CWorkBenchesDlgAutoProxy;
// Construction
public:
CWorkBenchesDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CWorkBenchesDlg();
CButton* m_pButtons; // 动态按钮数组
CStringArray m_ButtonTexts; // 存储按钮文本
CStringArray m_ButtonActions; // 存储按钮动作
CStringArray m_ButtonActionsParam; // 存储按钮动作
int m_nButtonCount; // 按钮数量
CRect m_ButtonRect; // 按钮位置和大小
// Dialog Data
//{{AFX_DATA(CWorkBenchesDlg)
enum { IDD = IDD_WORKBENCHES_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWorkBenchesDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
CWorkBenchesDlgAutoProxy* m_pAutoProxy;
HICON m_hIcon;
BOOL CanExit();
// Generated message map functions
//{{AFX_MSG(CWorkBenchesDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnClose();
virtual void OnOK();
virtual void OnCancel();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
void Init();
void ReadButtonFile(LPCTSTR lpszFileName);
void CreateDynamicButtons();
void OnDynamicButtonClicked(UINT nID);
void ExecuteAction(int nIndex);
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_WORKBENCHESDLG_H__B4B7DEE0_3AE7_418A_A81B_F9DB41C5FB25__INCLUDED_)