金山开源界面BkWin熟悉的后做界面的效果还不错,但它的界面排版的特殊性,使得WTL的DDX(对话框数据交换)没法使用,具体原因是:
金山开源界面BkWin的对话框的所有控件都是用CBkDialogView来排版和管理。
所以WTL中的DDX是接收不到控件的消息
看原来实现的代码:
BOOL DDX_Text(UINT nID, LPTSTR lpstrText, int cbSize, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0)
{
//实际上T不是窗口控件的父窗口,所以导致下面的方法都是不成功的
T* pT = static_cast<T*>(this);
BOOL bSuccess = TRUE;
if(bSave)
{
HWND hWndCtrl = pT->GetDlgItem(nID);
int nRetLen = ::GetWindowText(hWndCtrl, lpstrText, cbSize / sizeof(TCHAR));
if(nRetLen < ::GetWindowTextLength(hWndCtrl))
bSuccess = FALSE;
}
else
{
ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength);
bSuccess = pT->SetDlgItemText(nID, lpstrText);
}
if(!bSuccess)
{
pT->OnDataExchangeError(nID, bSave);
}
else if(bSave && bValidate) // validation
{
ATLASSERT(nLength > 0);
if(lstrlen(lpstrText) > nLength)
{
_XData data = { ddxDataText };
data.textData.nLength = lstrlen(lpstrText);
data.textData.nMaxLength = nLength;
pT->OnDataValidateError(nID, bSave, data);
bSuccess = FALSE;
}
}
return bSuccess;
}
解决办法:
修改原来atlddx.h,专门处理金山界面库的处理。
BOOL DDX_Text(UINT nID, BSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0)
{
T* pT = static_cast<T*>(this);
BOOL bSuccess = TRUE;
if(bSave)
{
bSuccess =::GetDlgItemText(pT->GetViewHWND(),nID, bstrText);
}
else
{
USES_CONVERSION;
LPTSTR lpstrText = OLE2T(bstrText);
ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength);
bSuccess =::SetDlgItemText(pT->GetViewHWND(),nID, lpstrText);
}
if(!bSuccess)
{
pT->OnDataExchangeError(nID, bSave);
}
else if(bSave && bValidate) // validation
{
ATLASSERT(nLength > 0);
if((int)::SysStringLen(bstrText) > nLength)
{
_XData data = { ddxDataText };
data.textData.nLength = (int)::SysStringLen(bstrText);
data.textData.nMaxLength = nLength;
pT->OnDataValidateError(nID, bSave, data);
bSuccess = FALSE;
}
}
return bSuccess;
}
修改后的文件:
bkddx.h