按:全画布显示时,按钮如果隐藏起来,画面显得更整洁。当然需要的时候,按钮还是显示出来,我们的的逻辑是这样,鼠标移到屏幕画面边缘则显示相应的按钮。
MFC窗口控件遍历
用MFC真是麻烦啊,我记得C#里面是有现成的控件数组的,而MFC需要自己查找。思想是利用API的子窗口查找函数,即EnumChildWindows函数。
BOOL EnumChildWindows(HWND hWndParent,WNDENUMPROC lpEnumFunc, LPARAM lParam);
三个参数
第一个:需要查找的窗口,
第二个:回调函数
第三个:传给回调函数的参数,这个参数自己定义。(随便定义)
笔者的目的是实现前面说明的按钮的显示和隐藏,第一步首先要找到符合要求的按钮,然后将这些按钮保存起来,以备用。为了方便,建立一个类,声明和定义如下:
//.h
#pragma once
#include <afxwin.h>
#include <vector>
using namespace std;
class CEnumCtrls
{
private:
CDialog *m_pDlg;
CRect m_rageRect;
vector<HWND> m_CtrlsVct;
public:
CEnumCtrls();
~CEnumCtrls();
void EnumCtrls(HWND pDlg, HWND hRangeCtrl);
bool ptInRect(CPoint pt);
void push_back(HWND hnd);
void showCtrl(bool bShow) {
for (auto it : m_CtrlsVct)
{
HWND hWnd;
hWnd = it;
ShowWindow(hWnd, bShow);
//CWnd *cWind;
//cWind = CWnd::FromHandle(hWnd);
//cWind->ShowWindow(true);
}
}
};
//.cpp
#include "stdafx.h"
#include "CEnumCtrls.h"
extern BOOL CALLBACK EnumChildWndProc(HWND hCtrlWind, LPARAM lParam);
//BOOL CALLBACK EnumChildWndProc(HWND hCtrlWind, LPARAM lParam);
CEnumCtrls::CEnumCtrls()
{
}
CEnumCtrls::~CEnumCtrls()
{
}
void CEnumCtrls::EnumCtrls(HWND pDlg, HWND hRangeCtrl)
{
CWnd *pWnd;
pWnd = CWnd::FromHandle(hRangeCtrl);
GetClientRect(hRangeCtrl, m_rageRect);
pWnd->ClientToScreen(m_rageRect);
EnumChildWindows(pDlg, EnumChildWndProc, (LPARAM)this);
}
bool CEnumCtrls::ptInRect(CPoint pt)
{
return m_rageRect.PtInRect(pt);
}
void CEnumCtrls::push_back(HWND hnd)
{
m_CtrlsVct.push_back(hnd);
}
BOOL CALLBACK EnumChildWndProc(HWND hCtrlWind, LPARAM lParam)
{
CWnd *pWnd;
pWnd = CWnd::FromHandle(hCtrlWind);
CEnumCtrls *cec = (CEnumCtrls*)lParam;
CRect ctrRect;
GetClientRect(hCtrlWind, ctrRect);
pWnd->ClientToScreen(ctrRect);
WCHAR txt[10];
GetWindowText(hCtrlWind, txt, 10);
CPoint ltPnt(ctrRect.left, ctrRect.top);
if (cec->ptInRect(ltPnt)) {
cec->push_back(hCtrlWind);
}
return TRUE;
}
类的成员变量 m_CtrlsVct记录符合要求的控件,成员函数 EnumCtrls用于查找符合条件的控件。在IDE里我用一个group控件将需要操纵的按钮包围起来,然后在程序的OnInitDialog事件中查找符合条件的控件:即控件如果在group范围内,则是符合条件的控件。在OnInitDialog 中的代码为:
…
// search all of the controls in the bottom and store them in a class
HWND dlgHwnd;
dlgHwnd = GetSafeHwnd();
m_EnumCtrls.EnumCtrls(dlgHwnd, GetDlgItem(IDC_STATIC_BTN_GROUP)->m_hWnd);
…
m_EnumCtrls 为上面类的一个实例,作为本对话框类的一个成员变量。
这样这些符合条件的控件就被记录下来了。
下面是判断隐藏和显示的判断代码,此代码放在MouseMove事件中。
...
grp->GetClientRect(rect);//获取Picture控件的位置信息,存入rect中
grp->ClientToScreen(rect);
bool bShowCtr=false;
bShowCtr = rect.PtInRect(point);//判断point是否在rect内部
//grp->ShowWindow(bShowCtr);
m_EnumCtrls.showCtrl(bShowCtr);//显示或者隐藏按钮
...
上述代码已经经过测试,下面展示一下效果
鼠标在屏幕下方进入group范围之内时:
鼠标离开group范围时,
到此为止,基本功能已经实现了,剩下的是显示风格的增加和调整。
拟需要增加的功能
1、按钮扁平化处理
2、鼠标点击处动画水纹效果
3、花样显示效果
4、幻灯片效果
5、背景音乐
6、图片说明记录
7、相机参数显示
8、简单美图处理
9、对象识别(人,车等)
2020-03-31 于泛五道口地区