大家好,我是Sean!
最近基于MFC做了个小软件,在此记录一下MFC的一些知识点。

创建基于对话框的一个应用

关键步骤如上述截图,后面点击下一步知道完成即可。

关于MFC界面控件的使用

通过左侧资源视图可以找到Dialog、Menu、Icon等文件,
我们可以往Dialog中添加控件,如按钮、编辑框。添加完控件之后,可以通过修改属性修改控件的ID及其他属性,并可以通过右键添加事件处理程序(回调函数),添加变量到对话框类当中。

Button 普通按钮

按钮事件处理程序,这个比较简单,一般就用单击或双击回调函数
(BN_CLICKED BN_DOUBLECLICKED)

具体点击后的逻辑在回调函数中实现即可:

void CVisionFastInputDlg::OnBnClickedAddButton()
{
  // code ...
}

Edit Control 普通文本编辑框

普通文本编辑框事件处理程序,我使用了EN_CHANGE,当编辑框中的内容有变化的时候,触发回调。

常用代码操作如下:

void My_Dlg::OnEnChangeTextValueEdit()
{
  // 获取文本框内容
    CString value;
    GetDlgItemText(IDC_TEXT_VALUE_EDIT, value);
  // CString转std::string
    std::string v = CT2A(value);
  // std::string转CString
    m_value = v.c_str();
  // 获取光标位置
  POINT cp = m_value_edit.GetCaretPos();
  // 设置光标位置
    SetCaretPos(cp);
    ShowCaret();
  // 更新数据,FALSE代表从代码中的变量更新到界面,TRUE代表从界面更新到代码中的变量
    UpdateData(FALSE);
}

Static Text 静态文本

这个在设置属性的时候直接把内容填写好就行了。

List Control 表格

这个属性设置要讲View设置为Report,这样才能是表格样式,并通过右键添加变量将其添加到界面类中,这个控件有些初始化的操作,回调函数常用NM_DBLCLK、NM_CLICK,及单击双击回调,单击回调可以用来刷新index,双击回调可以用来触发新的对话框。

常用代码如下:

  // 头文件中控件变量
  CListCtrl m_list;
  
  // 添加表头
    CString colums[] = {TEXT("No"), TEXT("Name"), TEXT("Sex")};
  
  // 添加列并设置宽度
    m_list.InsertColumn(0, colums[0], LVCFMT_LEFT, 200);
    m_list.InsertColumn(1, colums[1], LVCFMT_LEFT, 800);
    m_list.InsertColumn(2, colums[2], LVCFMT_LEFT, 200);
  // 最后一列自适应宽度
    m_list.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER);
    
    // 设置属性,单行选中
    m_list.SetExtendedStyle(m_shortcut_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );
  
  // 添加第一行数据
  m_list.InsertItem(0, TEXT("1001"));
  m_list.SetItemText(0, 1, TEXT("Henry Ha"));
  m_list.SetItemText(0, 2, TEXT("Male"));
  // 添加第二行数据
  m_list.InsertItem(1, TEXT("1002"));
  m_list.SetItemText(2, 1, TEXT("Marry Li"));
  m_list.SetItemText(3, 2, TEXT("Male"));
  
  // 删除所有行
  m_list.DeleteAllItems();

Combo-box Control 下拉选择框

这个是个下拉菜单,添加回调函数ON_CBN_SELCHANGE

CComboBox m_cbx;
// 添加选项
m_cbx.InsertString(0, _T("Red"));
m_cbx.InsertString(1, _T("Black"));
// 设置程序启动默认显示第0个
m_cbx.SetCurSel(0);


ON_CBN_SELCHANGE(IDC_DATASOURCE, &CVisionFastInputDlg::OnCbnSelchange)

void My_Dlg::OnCbnSelchange()
{
    // TODO: 在此添加控件通知处理程序代码
    int index = m_cbx.GetCurSel();
}

杂项

  1. 禁用/启用按钮
m_btn.EnableWindow(TRUE);
m_btn.EnableWindow(FALSE);
  1. 设置对话框标题
SetWindowText(_T("Amazing Application"));
  1. 给按钮添加提示内容
CToolTipCtrl m_ToolTip;
m_ToolTip.Create(this);
m_ToolTip.AddTool(&m_btn, _T("This is my button"));
  1. 注册、注销热键
// 监听热键消息
ON_MESSAGE(WM_HOTKEY, &My_Dlg::OnHotKey);

// 声明
afx_msg LRESULT OnHotKey(WPARAM wParam, LPARAM lParam);


// 自定义一个热键数值 WM_HOTEKY_SAVE,注册热键Ctrl + Shift + S
bool ret = ::RegisterHotKey(this->GetSafeHwnd(), WM_HOTEKY_SAVE, MOD_CONTROL | MOD_SHIFT, 'S');
ret = UnregisterHotKey(GetSafeHwnd(), WM_HOTEKY_SAVE);
  1. 最小化到托盘区及托盘区图标销毁
void My_Dlg::CloseAndHide()
{
    //接收到关闭消息时主窗口隐藏 
    NOTIFYICONDATA m_nid;
    m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
    m_nid.hWnd = this->m_hWnd;
    m_nid.uID = IDR_MAINFRAME;
    m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
    m_nid.uCallbackMessage = WM_SHOWTASK;//自定义的消息名称  
    wcscpy_s(m_nid.szTip, _T("Application"));
    m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
    Shell_NotifyIcon(NIM_ADD, &m_nid);//在托盘区添加图标  
    ShowWindow(SW_HIDE);//隐藏主窗口 
    UnHotKey();
}

void My_Dlg::DeleteTray()//销毁托盘图标
{
    Shell_NotifyIcon(NIM_DELETE, &m_nid);
}
  1. 托盘区的操作
// 监听消息
ON_MESSAGE(WM_SHOWTASK, &My_Dlg::OnShowTask)

// 声明
afx_msg LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);


LRESULT My_Dlg::OnShowTask(WPARAM wParam, LPARAM lParam)
{//wParam接收的是图标的ID,而lParam接收的是鼠标的行为 
    if (wParam != IDR_MAINFRAME) return 1;
    switch (lParam)
    {
    case WM_LBUTTONUP://左键单击显示主界面
    {
        SetHotKey();
        this->ShowWindow(SW_SHOW);
        SetForegroundWindow();
        DeleteTray();
    }break;
    case WM_RBUTTONUP://右击弹出菜单
    {
        LPPOINT lpoint = new tagPOINT;
        ::GetCursorPos(lpoint);//得到鼠标位置
        CMenu menu;
        menu.CreatePopupMenu();
        menu.AppendMenuW(MFT_STRING, IDR_SHOW, _T("Open"));
        menu.AppendMenuW(MFT_STRING, IDR_TRIGER, _T("Disable"));
        menu.AppendMenuW(MFT_STRING, IDR_TRIGER, _T("Enable"));
        menu.AppendMenuW(MFT_STRING, IDR_EXIT, _T("Exit"));
        SetForegroundWindow();
        int xx = TrackPopupMenu(menu, TPM_RETURNCMD, lpoint->x, lpoint->y, NULL, this->m_hWnd, NULL);//显示菜单并获取选项ID
        if (xx == IDR_SHOW)
        {
            SetHotKey();
            this->ShowWindow(SW_SHOW);
            SetForegroundWindow();
            DeleteTray();
        }
        else if (xx == IDR_TRIGER)
        {
  
        }
        else if (xx == IDR_EXIT) 
        { 
            DeleteTray();
            HMENU hmenu = menu.Detach();
            menu.DestroyMenu();
            delete lpoint;
            ExitProcess(0); 
        }
        HMENU hmenu = menu.Detach();
        menu.DestroyMenu();
        delete lpoint;
    }break;
    case WM_LBUTTONDBLCLK:
    {
        //双击不处理
    }break;
    }
    return 0;
}
  1. 提示框
HWND hPreWnd;
if (hPreWnd = ::FindWindow(NULL, _T("Application")))
{
    // MB_SYSTEMMODAL为阻塞模式
    bool ret = ::MessageBox(hPreWnd, _T("Are you sure to delete all!"), _T("Warning!"), MB_YESNO | MB_SYSTEMMODAL);
}
  1. 程序单例
void My_Dlg::SingletonInstance()
{
    HWND hPreWnd;

    if (hPreWnd = ::FindWindow(NULL, _T("Application")))
    {
        ::ShowWindow(hPreWnd, SW_SHOW);
        ::SetForegroundWindow(hPreWnd);
        ExitProcess(0);
    }
}

今天就分享到这里啦!感谢各位的阅读!码字不易,如果本文对你有帮助的话,帮忙点个赞吧~


CodeCooker
10 声望3 粉丝

人生如逆旅,我亦是行人,但愿初相遇,不负有心人,分享程序员成长路上的点点滴滴。