12.对话框和对话框类CDialog(7)

2019-02-15 22:03

value.Empty();

}

value.ReleaseBuffer();

}

else//FALSE,写内容到列表框 {

// 把value字符串写入当前选中的条目

if (::SendMessage(hWndCtrl, LB_SELECTSTRING,

(WPARAM)-1,(LPARAM)(LPCTSTR)value) == LB_ERR)

{

// no selection match

TRACE0(\

}

} }

DDX_LBString用来在列表框和CString类型的成员数据之间交换数据。首先,得到列表框的句柄,然后,调用Win32的列表框操作函数读取或者修改列表框的内容。

?

下面的DDX_Control用于得到一个有效的控制类型窗口对象(MFC对象)。

void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl) {

if (rControl.m_hWnd == NULL) // 还没有子类化 {

ASSERT(!pDX->m_bSaveAndValidate);

//得到控制窗口句柄

HWND hWndCtrl = pDX->PrepareCtrl(nIDC);

//把hWndCtrl窗口和MFC窗口对象rControl捆绑在一起 if (!rControl.SubclassWindow(hWndCtrl)) {

ASSERT(FALSE); //不允许两次子类化 AfxThrowNotSupportedException();

}

#ifndef _AFX_NO_OCC_SUPPORT//OLE控制相关的操作

else

{

// If the control has reparented itself (e.g., invisible control),

// make sure that the CWnd gets properly wired to its control site.

if

(pDX->m_pDlgWnd->m_hWnd != ::GetParent(rControl.m_hWnd))

rControl.AttachControlSite(pDX->m_pDlgWnd);

}

#endif //!_AFX_NO_OCC_SUPPORT

}

}

DDX_Control用来把控制窗口(Windows窗口)和一个对话框成员(MFC窗口对象)捆绑在一起,这个过程是通过SubclassWindow函数完成的。这样,程序员就可以通过成员变量来操作控制窗口,读、写、修改控制窗口的内容。

MFC还提供了许多其他数据交换函数(“DDX_”为前缀)和数据验证函数(“DDV_”为前缀)。DDV函数和DDX函数类似,这里不再多述。

程序员可以创建自己的数据交换和验证函数并使用它们,可以手工加入这些函数到DoDataExchange中,如果要Classwizard使用这些函数,可以修改DDX.CLW文件,在DDX、DDV函数入口中加入自己创建的函数。

1. UpdateData函数

有了数据交换类和数据交换函数,怎么来使用它们呢?MFC设计了UpdateData函数来完成上述数据交换和验证的处理。

首先,UpdateData创建CDataExchange对象,然后调用DoDataExchange函数。其实现如下:

BOOL CWnd::UpdateData(BOOL bSaveAndValidate) {

ASSERT(::IsWindow(m_hWnd)); // calling UpdateData before DoModal? //创建CDataChange对象

CDataExchange dx(this, bSaveAndValidate); //防止在UpdateData期间派发通知消息给该窗口

_AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); HWND hWndOldLockout = pThreadState->m_hLockoutNotifyWindow; ASSERT(hWndOldLockout != m_hWnd); // must not recurse pThreadState->m_hLockoutNotifyWindow = m_hWnd; BOOL bOK = FALSE; // assume failure TRY {

//数据交换

DoDataExchange(&dx); bOK = TRUE; // it worked

}

CATCH(CUserException, e)//例外 {

// validation failed - user already alerted, fall through ASSERT(bOK == FALSE);

// Note: DELETE_EXCEPTION_(e) not required

}

AND_CATCH_ALL(e)

{

// validation failed due to OOM or other resource failure e->ReportError(MB_ICONEXCLAMATION, FX_IDP_INTERNAL_FAILURE); ASSERT(!bOK); DELETE_EXCEPTION(e);

}

END_CATCH_ALL //恢复原来的值

pThreadState->m_hLockoutNotifyWindow = hWndOldLockout; return bOK; }

UpdataDate根据参数创建CDataExchange对象dx,如果参数为TRUE,dx用来写数据,否则dx用来读数据;然后调用DoDataExchange进行数据交换。在数据交换期间,为了防止当前窗口接收和处理命令通知消息,在当前线程的线程状态中记录该窗口的句柄,用来防止给该窗口发送通知消息。

使用MFC的数据交换和验证机制,大大简化了程序员的工作。通常在OnInitDialog中,MFC调用UpdateData(FALSE)把数据送给控制窗口显示;在OnOk中,调用UpdateData(TRUE)从控制窗口中读取数据。

1. 无模式对话框

CFormView是MFC使用无模式对话框的一个典型例子。CFormView是基于对话框模板创建的视,它的直接基类是CSrcollView,CSrcollView的直接基类才是CView。所以,这里先对CScorllView作一个简要的介绍。

1. CScrollView

CScrollView继承了CView的特性,并且增加了如下的功能:

(1)管理映射模式、窗口尺寸、视口尺寸(Map mode、Window and Viewport size)。Window and Viewport size用来完成页面空间到设备空间的转换。 (2)自动管理滚动条,响应滚动条消息。

为了实现这些功能,CScrollView覆盖CView或者CWnd的一些虚拟函数和消息处理函数,添加了一些新的函数,当然也设计了新的成员变量。

?

CscrollView新的成员变量

protected: int m_nMapMode;

CSize m_totalLog; // total size in logical units (no rounding) CSize m_totalDev; // total size in device units

CSize m_pageDev; // per page scroll size in device units CSize m_lineDev; // per line scroll size in device units BOOL m_bCenter; // Center output if larger than total size BOOL m_bInsideUpdate; // internal state for OnSize callback

?

CScrollView新的成员函数,用来完成和滚动操作、滚动条等有关的功能

void SetScaleToFitSize(SIZE sizeTotal);

void SetScrollSizes(int nMapMode, SIZE sizeTotal, const SIZE& sizePage = sizeDefault, const SIZE& sizeLine = sizeDefault);


12.对话框和对话框类CDialog(7).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:开放性试题测试

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: