[6]打造自己的“按钮激活专家”---实践性很强,得跟着练习。

学习收货。
01,这节课搞定了4个函数,实现了2个功能。
第一个功能是窗口置顶功能,很不错。
第二个功能是激活灰色按钮,很不错。

02,置顶窗口函数的实现


image.png

详细解读:
checkbox控件,没有绑定控件变量,也能得到其控件id的指针。
//想知道单选框是否被选中,需要或得其空间变量。由于没有用绑定空间变量,采用的是这种方法。
CButton pTopMostCheck = (CButton)GetDlgItem(IDC_CHECK1);
int iCheck = pTopMostCheck->GetCheck();
然后调用CButton类的方法Getcheck()
GetCheck()在CSDN中是这样说的:
CButton::GetCheck

int GetCheck( ) const;

返回值:
对于采用BS_AUTOCHECKBOX、BS_AUTORADIOBUTTON、BS_AUTO3STATE、BS_CHECKBOX、BS_RADIOBUTTON或BS_3STATE风格建立的按钮,返回值为下列之一: 值 含义
0 按钮处于未选中状态
1 按钮处于选中状态
2 按钮状态不定(仅当按钮风格为BS_3STATE或BS_AUTO3STATE时)如果按钮是其它风格,则返回0。

说明:本函数用于检测单选钮或复选框的选中状态。

下面定义的宏,很清楚了。


image.png

==========
接下来,设计到SetWindowPos教程地址:https://www.cnblogs.com/findumars/p/3948315.html

image.png

03,关于设置MFC计时器的实现:
第一步,编写OnTimer函数


image.png

第二步,启动,或者关闭。


image.png

04,枚举得到所有子窗口,得有一个回调函数。

//枚举hTopWnd的所有子窗口,也就是子控件。
EnumChildWindows(hTopWnd, EnumChildProc, NULL);


image.png

===========================


image.png

image.png

image.png

image.png

=================================================
======17分钟开始讲解置顶功能。


image.png

23分钟50秒,置顶功能讲解完毕

image.png

image.png

======================================================================


image.png

绑定一个类,
image.png

image.png

添加窗口回调函数


image.png

image.png

======================
老师视频中的代码如下:

//置顶窗口按钮---check
void CVC_AnniuDlg::OnBnClickedCheck1()
{
    // TODO:  在此添加控件通知处理程序代码
    //想知道单选框是否被选中,需要或得其空间变量。由于没有用绑定空间变量,采用的是这种方法。
    CButton *pTopMostCheck = (CButton*)GetDlgItem(IDC_CHECK1);
    int iCheck = pTopMostCheck->GetCheck();
    if (iCheck==BST_CHECKED )
    {
        SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
    }
    else
    {
        SetWindowPos(&CWnd::wndNoTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
    }


}

//按钮,开始激活或者停止。
void CVC_AnniuDlg::OnBnClickedButton1()
{
    // TODO:  在此添加控件通知处理程序代码
    static BOOL bStart = FALSE;
    if (bStart ==FALSE )
    {
        bStart = TRUE;
        GetDlgItem(IDC_BUTTON1)->SetWindowText(_T("停止!"));
        SetTimer(1, 200, NULL);
    }
    else
    {
        bStart = FALSE;
        GetDlgItem(IDC_BUTTON1)->SetWindowText(_T("开始激活!"));
        KillTimer(1);
    }
}

//EnumChildProc,放在上面
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
{
    if (!IsWindowEnabled(hWnd) )
    {
        EnableWindow(hWnd, true);   
    }
    return true;
}

void CVC_AnniuDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    TCHAR szTitle[MAX_PATH] = { 0 };
    HWND hTopWnd = ::GetForegroundWindow();
    ::GetWindowText(hTopWnd, szTitle, MAX_PATH);
    SetDlgItemText(IDC_EDIT1,szTitle );

    //枚举hTopWnd的所有子窗口,也就是子控件。
    EnumChildWindows(hTopWnd, EnumChildProc, NULL);

    CDialogEx::OnTimer(nIDEvent);
}

============================
接下来的代码,我已经做好了备注方面的内容:


image.png

image.png
image.png

image.png

//置顶窗口按钮---check
void CVC_AnniuDlg::OnBnClickedCheck1()
{
    // TODO:  在此添加控件通知处理程序代码

    //想知道单选框是否被选中,需要或得其空间变量。由于没有用绑定空间变量,采用的是这种方法。
    CButton *pTopMostCheck = (CButton*)GetDlgItem(IDC_CHECK1);
    /*
    GetDlgItem用于获得指定控件ID的窗体指针
    GetDlgItem(对话框句柄,控件ID)得到句柄,再操作。
    */
    int iCheck = pTopMostCheck->GetCheck();  
    /*//然后调用CButton类的方法Getcheck()
    GetCheck()在CSDN中是这样说的:
    CButton::GetCheck

    int GetCheck( ) const;

    返回值:
    对于采用BS_AUTOCHECKBOX、BS_AUTORADIOBUTTON、BS_AUTO3STATE、BS_CHECKBOX、BS_RADIOBUTTON或BS_3STATE风格建立的按钮,返回值为下列之一: 值 含义
    0 按钮处于未选中状态
    1 按钮处于选中状态
    2 按钮状态不定(仅当按钮风格为BS_3STATE或BS_AUTO3STATE时)如果按钮是其它风格,则返回0。

    说明:本函数用于检测单选钮或复选框的选中状态。

    */
    if (iCheck==BST_CHECKED )
    {
        SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
        //,SetWindowPos教程地址:https://www.cnblogs.com/findumars/p/3948315.html

    }
    else
    {
        SetWindowPos(&CWnd::wndNoTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
    }

    
}

//按钮,开始激活或者停止。
void CVC_AnniuDlg::OnBnClickedButton1()
{
    // TODO:  在此添加控件通知处理程序代码
    static BOOL bStart = FALSE;
    if (bStart ==FALSE )
    {
        bStart = TRUE;
        GetDlgItem(IDC_BUTTON1)->SetWindowText(_T("停止!"));
        //3、启动定时器
        SetTimer(1, 200, NULL); //在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了,函数返回值就是第一个参数值1,表示此定时器的ID号。
        //SetTimer()函数使用:https://www.cnblogs.com/lingc/p/3380919.html

    }
    else
    {
        bStart = FALSE;
        GetDlgItem(IDC_BUTTON1)->SetWindowText(_T("开始激活!"));
        //4、关闭定时器
        KillTimer(1);  //在MFC程序中我们可以直接调用KillTimer(int nIDEvent)来取消定时器。1代表序号,上面setTimer里第一个参数
    }
}

//EnumChildProc,放在上面
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
{
    if (!IsWindowEnabled(hWnd) )
        //函数功能:该函数用于判断指定的窗口是否允许接受键盘或鼠标输入。返回值:若窗口允许接受键盘或鼠标输入,则返回非0值,若窗口不允许接受键盘或标输入,则返回值为0。备注:子窗口只有在被允许并且可见时才可接受输入。
    {
        EnableWindow(hWnd, true);   
        //该函数允许/禁止指定的窗口或控件接受鼠标和键盘的输入,当输入被禁止时,窗口不响应鼠标和按键的输入,输入允许时,窗口接受所有的输入。
        //bEnable:定义窗口是被允许,还是被禁止。若该参数为TRUE,则窗口被允许。若该参数为FALSE,则窗口被禁止。
        // 如果窗口此前已禁用,则返回值是非零。 返回值是0,则窗口先前启用或错误。若想获得更多的错误信息,可调用GetLastError函数。
    }
    return true;
}


//MFC中定时器OnTimer函数的使用:https://blog.csdn.net/qq_33723441/article/details/54599022
//2、编写OnTimer函数
void CVC_AnniuDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    TCHAR szTitle[MAX_PATH] = { 0 };
    //GetForegroundWindow获取一个前台窗口的句柄(用户当前工作的窗口)
    HWND hTopWnd = ::GetForegroundWindow();
    ::GetWindowText(hTopWnd, szTitle, MAX_PATH);
    SetDlgItemText(IDC_EDIT1,szTitle );

    //枚举hTopWnd的所有子窗口,也就是子控件。
    EnumChildWindows(hTopWnd, EnumChildProc, NULL);
    /*
    BOOL WINAPI EnumChildWindows(  _In_opt_  HWND hWndParent,  _In_      WNDENUMPROC lpEnumFunc,  _In_      LPARAM lParam );
    hWndParent: 需要枚举父窗口的句柄,如果此值为空EnumWindows函数
    lpEnumFunc: 定义回调函数的指针 (回调函数名)
    lParam: 传递给回调函数的值

    */

    CDialogEx::OnTimer(nIDEvent);
}

你可能感兴趣的:([6]打造自己的“按钮激活专家”---实践性很强,得跟着练习。)