常见的两种类和类之间相互调用的方法。
16.1 用户权限信息在不同对话框之间共享
①在CWokerApp类中定义变量:
class CWorkerApp : public CWinApp
{
public:CWorkerApp();SAdmin m_admin;//登录信息
// 重写
public:virtual BOOL InitInstance();
// 实现DECLARE_MESSAGE_MAP()
};
②在CLoginDlg类中进行赋值
BOOL CLoginDlg::CheckPass(CString szName, CString szPass)
{//TRUE代表登录成功CFile file;if (!file.Open(_T("admin.dat"), CFile::modeRead)){CreateUser();if (!file.Open(_T("admin.dat"), CFile::modeRead))return FALSE;}SAdmin a;while (file.Read(&a, sizeof(a)) == sizeof(a)){if (!szName.CompareNoCase(a.sName)){if (szPass == a.sPass){theApp.m_admin = a;return TRUE;}}}return FALSE;
}
③在CMainDlg类中进行访问应用,采用引用型变量
BOOL CMainDlg::OnInitDialog()
{CDialogEx::OnInitDialog();CString str = _T("控制面板 - ");SAdmin &a = theApp.m_admin;str += a.sName;str += _T("(");str += a.nPrior ? _T("普通") : _T("高级");str += _T(")");SetWindowText(str);if (a.nPrior)GetDlgItem(IDC_PRIOR) ->EnableWindow(FALSE);//GetDlgItem(IDC_PRIOR)->ShowWindow(SW_HIDE);//ShowWindow EnableWindowreturn TRUE;
}
16.2 其他对话框访问主对话框(AfxGetMainWnd)
①在CWorkerApp类中指定主对话框
BOOL CWorkerApp::InitInstance()
{CLoginDlg dlg;if (IDCANCEL == dlg.DoModal())return FALSE;while (true){…case IDC_INFO:{CWorkerDlg dlg;m_pMainWnd = &dlg;dlg.DoModal();break;}…}}return FALSE;
}
②在其他对话框中使用全局函数AfxGetMainWnd获取主对话框指针并访问
void CInputDlg::AddToList()
{
if (AfxMessageBox(_T(“是否添加?”), MB_YESNO) == IDNO)
return;
CString str;
GetDlgItemText(IDC_NUMB, str);
CWorkerDlg* pDlg = (CWorkerDlg*)AfxGetMainWnd();
if (pDlg ->CheckNumber(str))return;
int i = pDlg->m_list.GetItemCount();
pDlg->m_list.InsertItem(i, str);
GetDlgItemText(IDC_NAME, str);
}
16.3 其他对话框访问主对话框(m_pDlg)
思想:直接定义指针变量指向要访问的对话框,这种方法其实没有主对话框
①在CInputDlg类中定义CWorkerDlg类型的指针变量,用来指向CWorkerDlg对话框;需要CInputDlg类中包含CWorkerDlg的头文件或进行声明,然而在头文件中进行包含容易造成类与类之间相互包含的混乱错误,因此可以进行声明;这种声明其实是假声明,只适用于指针类型,不适用于对象。
这种声明可以防止类与类在头文件中相互包含、重复包含而引起的错误。
//#include "WorkerDlg.h"
class CWorkerDlg;
class CInputDlg : public CDialogEx
{DECLARE_DYNAMIC(CInputDlg)
public:CWorkerDlg *m_pDlg; //定义CWorkerDlg对象指针CInputDlg(CWnd* pParent = NULL); // 标准构造函数virtual ~CInputDlg();
…
};
在stdafx.h中可禁用warning:
#pragma warning(disable:4005)
②在CInputDlg窗口弹出之前,将CWorkerDlg对象指针(this指针)赋值给①中定义的m_pDlg变量
void CWorkerDlg::OnBnClickedAdd()
{//排除重复工号的功能,当重复的工号禁止插入(已存在!)CInputDlg dlg;dlg.m_pDlg = this;dlg.DoModal();
}
16.4 消息反射:(控件内的消息映射到父窗口类)
a)所有子控件的内部消息都是通过WM_NOTIFY这个消息反射给父窗口;
b)不同的控件类型对应有不同的反射消息种类;
例如:BN_CLICK
代表Button Notify Click`(按钮点击消息)
LVN_ITEMCHANGED
代表List View Notify Item Changed
(选中项变化了)
16.5 在CWnd类中常见的等价关系:
a)判断父子关系:
BOOL IsChild( const CWnd* pWnd ) const; 判断窗口是否是一个子窗口
CWnd* GetParent(); 获取父窗口对象指针
m_list.GetParent() == pWnd 等价于pWnd ->IsChild(&m_list);
b)判断是否是最大化:pWnd ->GetStyle() & WS_MAXIMIZE`
BOOL IsIconic( ) const; 判断窗口是否是最小化的状态
BOOL IsZoomed( ) const; 判断窗口是否是最大化的状态
c)判断是否可见:GetStyle() & WS_VISIBLE
BOOL IsWindowVisible( ) const; 判断窗口是否是可见的
void CTestdDlg::OnBnClickedIsVisible()
{CWnd *pOK = GetDlgItem(IDOK);//if ()//pOK ->IsWindowVisible// ;//else// pOK->ShowWindow(SW_SHOW);pOK->ShowWindow(pOK->GetStyle()&WS_VISIBLE ? SW_HIDE : SW_SHOW);
}
d)判断是否可用:GetStyle() & WS_DISABLED
BOOL IsWindowEnabled( ) const; 判断窗口是激活的还是禁用的
void CTestdDlg::OnBnClickedDisabled()
{CWnd *pWnd = GetDlgItem(IDCANCEL);//pWnd->EnableWindow(!pWnd->IsWindowEnabled());pWnd->EnableWindow(pWnd->GetStyle() & WS_DISABLED);
}
16.6 CWnd类中常见的静态成员函数:
static CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName);
根据窗口类型名或窗口标题名查找窗口;static CWnd* PASCAL GetFocus( ); 获取焦点所在的窗口
CWnd* SetFocus( ); 将一个窗口设置为焦点窗口
static CWnd* PASCAL GetActiveWindow( ); (进程内的)获取活动窗口
CWnd* SetActiveWindow( ); (进程内的)将一个窗口设置为活动窗口 static CWnd* PASCAL GetForegroundWindow( ); 获取所有任务栏主窗口中最前端的窗口
BOOL SetForegroundWindow( ); 将主窗口推到任务栏中所有窗口的最前端CWnd* GetTopWindow( ) const; 获取所有重叠窗口中最前端的窗口
void BringWindowToTop( ); 将主窗口推到重叠窗口的最前端
BOOL FlashWindow( BOOL bInvert ); 让窗口在任务栏中闪烁以下
void CTestdDlg::OnBnClickedGetForeGround()
{CWnd* p = CWnd::FindWindow(_T("NotePad"), NULL);if(p){p->SetForegroundWindow();p->FlashWindow(TRUE);}
}
HICON GetIcon( BOOL bBigIcon ) const; 获取窗口图标 HICON SetIcon( HICON hIcon, BOOL bBigIcon ); 设置窗口图标 static CWnd* PASCAL GetDesktopWindow( ); 获取Windows桌面窗口 static CWnd* PASCAL GetCapture( ); 获取捕捉鼠标活动的窗口 CWnd* SetCapture( ); 将窗口设置为捕捉鼠标活动的窗口 int GetWindowRgn( HRGN hRgn )const; 获取不规则窗口的区域 int SetWindowRgn( HRGN hRgn, BOOL bRedraw ); 按照指定的区域将窗口设置为不规则形状 void MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint=TRUE ); 根据指定的位置移动窗口 void MoveWindow(LPCRECT pRect, BOOL bRepaint = TRUE ); 根据指定的矩形区域移动窗口 BOOL SetWindowPos(const CWnd* pWndAfter, int x, int y, int cx, int cy, UINT nFlags ); 不但移动窗口的x,y坐标位置,而且还改变窗口的Z轴次序 void CenterWindow( CWnd* pOwner = NULL ); 将窗口居中,对应父窗口或者屏幕的中央 void GetWindowRect( LPRECT lpRect ) const; 获取窗口在屏幕坐标中的矩形区域 void GetClientRect( LPRECT lpRect ) const; 获取窗口的客户区的矩形区域 static CWnd* WindowFromPoint( POINT point ); 获取屏幕中某个坐标点上的窗口 CWnd* ChildWindowFromPoint( POINT point ) const; 获取客户区内某个坐标点上的子窗口 static CWnd* FindWindow(LPCTSTR szClassName, LPCTSTR lpszWindowName ); 根据类名或者标题名查找一个主窗口
CWnd* GetOwner( ) const; 获取拥有者窗口 void SetOwner( CWnd* pOwnerWnd ); 将窗口设置为被另一个窗口拥有 CWnd* GetParent( ) const; 获取父窗口 CWnd* SetParent( CWnd* pWndNewParent ); 为窗口设置一个新的父窗口 CWnd*GetNextWindow(UINTnFlag =GW_HWNDNEXT ) const; 获取z序中的前一个或后一个窗口,可以联合GetTopWindow对同等级窗口遍历 CWnd* GetWindow( UINT nCmd ) const; 全面获取窗口,包括父子窗口前后窗口等 int GetDlgCtrlID( ) const; 获取一个窗口的ID int SetDlgCtrlID( int nID ); 给窗口设置一个新的ID