C++ MFC万能的类向导

类向导图解

命令
消息
虚函数
成员变量
方法
难怪数MFC简单,只要你掌握了类向导,你基本就已经掌握了MFC了,毕竟布局和代码都是自动生成,再加上C++基础上手还是挺快的,剩下的就是多多练习了。

右键图标MENU
申明:

因为是自定义消息 所以需要一个位置ID 建议大于100,.

#define WM_SHOWTASK (WM_USER + 123)
//类中申明
afx_msg LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);
//BEGIN_MESSAGE_MAP内加入
ON_MESSAGE(WM_SHOWTASK, OnShowTask)
调用
LRESULT CNumToChineseDlg::OnShowTask(WPARAM wParam, LPARAM lParam)
//wParam接收的是图标的ID,lParam接收的是鼠标的动作----最小化到托盘
{
    if (wParam != IDR_MAINFRAME)
        return 1;
    // // 双击左键的处理
    if (WM_LBUTTONDBLCLK == lParam)
    {
        // 显示主窗口 
        this->ShowWindow(SW_SHOWNORMAL);
        this->SetForegroundWindow();
        Shell_NotifyIcon(NIM_DELETE, &nid); // 托盘图标不显示
    }
    if (lParam == WM_RBUTTONDOWN)
    {
        //右击弹出托盘菜单
        CMenu menu;
        menu.LoadMenu(IDR_MENU1);//首先建立菜单项IDR_MENU2
        CMenu *pPopUp = menu.GetSubMenu(0);
        CPoint pt;
        GetCursorPos(&pt);//得到光标处
        SetForegroundWindow();
        pPopUp->TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);//确保右键点击在哪菜单出现在哪
        //PostMessage(WM_NULL, 0, 0);
        PostMessage(WM_MY_MESSAGE, 0, 0);//发送自定义消息
    }
    return 0;
}
生成IDR_MENU1

流程:资源视图 ->MENU->右键->添加资源->Menu->新建
绑定点击事件:右键选中item->添加事件处理程序(当然是单击时间啦)

//BEGIN_MESSAGE_MAP里面申明
ON_COMMAND(ID_NICE_32787, &CNumToChineseDlg::onMenuDestory)
//调用:图片菜单一被点击 关闭程序
void CNumToChineseDlg::onMenuDestory()
{
    // TODO: 在此添加命令处理程序代码
    CNumToChineseDlg::DestroyWindow();
}
申明全局变量:右键 ->添加变量
NOTIFYICONDATA nid;//
在CDialog的OnInitDialog函数中 初始化
    // TODO: Add extra initialization here
    nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);

    nid.hWnd = this->m_hWnd;

    nid.uID = IDR_MAINFRAME;

    nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;

    nid.uCallbackMessage = WM_SHOWTASK;

    nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));

    strcpy_s(nid.szTip, strlen("我是右下角最小图标的标题名称哦") + 1, "我是右下角最小图标的标题名称哦");

    Shell_NotifyIcon(NIM_ADD, &nid); // 在托盘区添加图标
自定义消息:
发消息
#define WM_MY_MESSAGE (WM_USER + 124)
PostMessage(WM_MY_MESSAGE, 0, 0);//发送自定义消息
申明消息
//BEGIN_MESSAGE_MAP里面加入申明
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
//类中加入申明
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
调用消息
LRESULT CNumToChineseDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
    return LRESULT();
}
虚函数OnPaint

这是一个系统函数,会被无限调用,通过重写来设置最小化图标的样式,或者修改窗口样式


void CNumToChineseDlg::OnPaint() 
{   //是否最小化显示最小化的图标 就像右下角的QQ图标一样 订制的
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(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
    {
        CPaintDC dc(this);
        CRect rect;
        GetWindowRect(&rect);
        ScreenToClient(&rect);
        CRect rc(0, rect.top, 1920, 1080);
        dc.FillSolidRect(rc, RGB(255, 255, 255));//*/
    }
    CDialog::OnPaint();
}
系统消息

很明显和自定义函数的不同是他没有参数。

    //创建上边框事件
    ON_WM_SYSCOMMAND()
    //窗口无限调用,绘制界面函数
    ON_WM_PAINT()
    //寻图函数?
    ON_WM_QUERYDRAGICON()
自定义函数:跟自定义消息的不同 是不需要到BEGIN_MESSAGE_MAP中加入消息队列。

操作:右键->类向导->方法->添加方法

申明
    //类中申明
    // 马齐写的测试添加函数的例子
    int changeMQ();
调用
// 马齐写的测试添加函数的例子
int CNumToChineseDlg::changeMQ()
{
    // TODO: 在此处添加实现代码.
    return 0;
}
控件与变量的绑定
数据交换函数:DoDataExchange为系统虚函数(理解为override函数)
//UpdateData(TRUE) == 将控件的值赋值给成员变量,即从窗口编辑框中读入数据
//UpdateData(FALSE) == 将成员变量的值赋值给控件,将数据从窗口显示。
void CNumToChineseDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //实现控件可变量的双向绑定
    DDX_Text(pDX, IDC_EDIT1, m_dmoney);
    DDX_Text(pDX, IDC_EDIT2, m_strChineseCapital);
    //打印日志
    /*char * str = "dismissed with Cancel";
    HANDLE HConsole;
    AllocConsole();
    HConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD dw;
    WriteConsole(HConsole, str, strlen(str), &dw, NULL);*/
}
申明
    //类中申明
    afx_msg void OnTrans();
    //BEGIN_MESSAGE_MAP中加入,IDC_TRANS为控件ID,OnTrans为函数名
    ON_BN_CLICKED(IDC_TRANS, OnTrans)
调用:UpdateData会调用DoDataExchange
//UpdateData(TRUE) == 将控件的值赋值给成员变量,即从窗口编辑框中读入数据
//UpdateData(FALSE) == 将成员变量的值赋值给控件,将数据从窗口显示。
void CNumToChineseDlg::OnTrans() 
{
    // TODO: Add your control notification handler code here
    //先读
    UpdateData(true);
    //
    m_strChineseCapital=ChineseCapitalMoney(m_dmoney)GetLength(size);
    //在赋值 显示
    UpdateData(false);
}
最后一个最定义函数

1.主要看API,如TrimLeft(trim),Format(new String),
2.这里的Cstrig貌似等价于_T(“”);

//输入数字型金额,返回中文大写金额

CString CNumToChineseDlg::ChineseCapitalMoney(double Num)
{
    CString szChMoney,szNum; 
    int iLen, iNum, iAddZero=0;
    TCHAR* hzUnit[18]={_T("分"),_T("角"),_T("元"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟"),_T("亿"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟")};
    TCHAR* hzNum[10]={_T("零"),_T("壹"),_T("贰"),_T("叁"),_T("肆"),_T("伍"),_T("陆"),_T("柒"),_T("捌"),_T("玖")};
    szNum.Format(_T("%18.0f"), Num*100); //只是到分
    szNum.TrimLeft();
    iLen=szNum.GetLength();
    if(iLen>15 || iLen==0 || Num<0)return ""; //数据错误返回

    for(int i=0;i<iLen;i++)
    {
        iNum=_ttoi((LPCTSTR)szNum.Mid(i,1));
        if(iNum==0)//如果为0
            iAddZero++;
        else
        {
            if(iAddZero>0) 
                szChMoney+=_T("零");
            szChMoney+=hzNum[iNum];//转换为相应的数字
            iAddZero=0;
        }   
        if(iNum!=0||iLen-i==3||iLen-i==11||((iLen-i+1)%8==0&&iAddZero<4))
        szChMoney+=hzUnit[iLen-i-1];//添加相应的汉字
    }
    if(szNum.Right(2)==_T("00")) //没有角和分
     szChMoney+=_T("整");
    return szChMoney;
}

PS:本博客基于《VC++400例》:实例006——实现数字金额的中文大写转换,加上自己一些修改,感兴趣的读者请联系作者拿源码。

猜你喜欢

转载自blog.csdn.net/qq_20330595/article/details/82497357