1. Dialog相关
1.1 将MFC的dialog封装成DLL供其他项目使用
https://blog.youkuaiyun.com/miko2018/article/details/83865022
找了很久,亲身实践可行 :)
1.2 dialog弹出方式
(一)DoModal()
CCurveDlg mydlg;
mydlg.DoModal();
(二)ShowWindow()
CCurveDlg *newDialog;
newDialog = new CCurveDlg;
newDialog->Create(IDD_DIALOG1, GetDesktopWindow());
newDialog->ShowWindow(SW_SHOW);
(三)获取dialog相对于屏幕的位置,根据相对位置弹出新的dialog
CCurveDlg *newDialog;
newDialog = new CCurveDlg;
newDialog->Create(IDD_DIALOG1, GetDesktopWindow());
//获取相对于屏幕的位置
CRect rect;
GetWindowRect(rect);
//设置新窗口出现的位置
newDialog->MoveWindow(rect.TopLeft().x+50, rect.TopLeft().y+50, rect.Width(), rect.Height());
newDialog->ShowWindow(SW_SHOW);
1.3 关闭父dialog,子dialog不要关闭
2. CMenu相关
关于CMenu很好的一篇文章: https://blog.youkuaiyun.com/gavingey/article/details/2214086
2.1 动态添加单层Menu (类型:MF_STRING)
// 假设在ChildFrm中,调用该方法获得当前的主菜单指针
CMenu* mainMenu = AfxGetMainWnd()->GetMenu();
CMenu* subMenu = NULL;
// 遍历主菜单下的各级菜单寻找名为MainSubMenu1的菜单
int menuCount = mainMenu->GetMenuItemCount();
for(int i = 0; i < menuCount; i++)
{
CString menuName;
if(mainMenu->GetMenuStringW(i,menuName, MF_BYPOSITION)
&& menuName == "打开")
{
subMenu = mainMenu->GetSubMenu(i);
break;
}
}
// 移除原有的菜单项
/*int subMenu1Count = subMenu->GetMenuItemCount();
for(int i = subMenu1Count - 1; i >= 0; i--)
{
subMenu->DeleteMenu(i, MF_BYPOSITION);
} */
// 动态添加Item菜单项
for(int i = 0; i < 2; i++)
{
CString message = _T("");
message.Format(_T("SubSubMenu%i"),i);
subMenu->AppendMenuW(MF_STRING, ID_BEGIN+i, message);
}
2.2 动态添加多层Menu (类型:MF_POPUP)
CMenu* mainMenu = NULL;
mainMenu = GetMenu();
if(mainMenu != NULL){
CMenu* subMenu = NULL;
subMenu = mainMenu->GetSubMenu(0);
if(subMenu != NULL) {
int itemsCnt = subMenu->GetMenuItemCount();
for (int i=0; i< itemsCnt; i++)
{
subMenu->DeleteMenu(0, MF_BYPOSITION);
}
subMenu->AppendMenuW(MF_STRING, (UINT)subMenu->m_hMenu+0, L"一级菜单0");
subMenu->AppendMenuW(MF_STRING, (UINT)subMenu->m_hMenu+1, L"一级菜单1");
subMenu->AppendMenuW(MF_SEPARATOR);
CMenu* sub2Menu = new CMenu(); //popup
sub2Menu->CreateMenu();
if(sub2Menu != NULL){
sub2Menu->AppendMenu( MF_STRING,(UINT)sub2Menu->m_hMenu+4, L"二级菜单0" );
sub2Menu->AppendMenu( MF_STRING,(UINT)sub2Menu->m_hMenu+1, L"二级菜单1" );
sub2Menu->AppendMenu( MF_STRING,(UINT)sub2Menu->m_hMenu+2, L"二级菜单2" );
sub2Menu->AppendMenu( MF_STRING,(UINT)sub2Menu->m_hMenu+3, L"二级菜单3" );
}
subMenu->AppendMenuW(MF_POPUP, (UINT_PTR)sub2Menu->operator HMENU(), L"PopupMenu");
}
}
2.3 为菜单动态添加点击事件
一篇比较好的介绍文章:https://www.cnblogs.com/sitemaker/articles/newbutton.html
我的需求是生成若干个子菜单,用同一个函数响应他们的点击事件,而后根据Id的不同,做不同的工作。
1.在(对话框).h中声明响应函数:
2.在(对话框).cpp中完成事件与函数的映射:
(1)在文件中找到BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()
(2)在这两句话中间写:
ON_COMMAND_RANGE(ID_STRNG_MYMENUS,ID_STRNG_MYMENUS+1000,OnMuseClick)
其中“ID_STRNG_MYMENUS”是我的宏定义,用来作为Muse的Id
#define ID_STRNG_MYMENUS 20000
表示Id在20000~21000之间的控件的点击事件都用“OnMuseClick()”函数响应
3.在(对话框).cpp中完成实现响应函数:
void CCurveDlg::OnMuseClick(UINT uID){
AfxMessageBox(path[uID-20000]);
}
3. 必备小知识
3.1 根据Id获取控件对象
CButton *p_button1 = (CButton *)GetDlgItem(IDC_MAN);
3.2 Edit Control 获取焦点
GetDlgItem(IDC_EDIT1)-> SetFocus();
3.3 枚举一个目录下的所有文件和子目录
void ListFolder(const CString & sPath)
{
CFileFind ff;
BOOL bFound = ff.FindFile(sPath + "\\*.*");
while(bFound)
{
bFound = ff.FindNextFile();
if(ff.IsDirectory()) //是目录
{
if(!ff.IsDots()) //不是本级目录或父目录(.和..)
ListFolder(ff.GetFilePath()); //递归子目录
}
else
{
AfxMessageBox(ff.GetFilePath()); //全路径
//AfxMessageBox(ff.GetFileTitle());//目录名
//AfxMessageBox(ff.GetFileName());//文件名
}
}
ff.Close();
}