что значит - в пользу ? У меня родитель - сам грид. Если щёлкнуть не по едиту в диалоге (то есть по гриду либо окружению грида), то диалог закрывается
в общем, сделано у меня было так (повыдирал из проекта)
файлы класса CEnterEditDialog диалога (ID ресурса диалога (int IDD) задаётся через конструктор)
Ресурс - абсолютно любой диалог
файл EnterEditDialog.h
#pragma once
class CEnterEditDialog : public CDialog
{
bool m_TheFirstPaint;
bool m_bCanCloseWhenWPCing;
bool m_bSaveIfLosfFocus;
enum{IDC_EDIT=1000};
CEdit m_edit;
static BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam);
public:
CString m_csText;
private:
CWnd* m_pParent;
RECT m_Rect;
//цвет фона окошка ввода
COLORREF m_ForeRGB;
//шрифт окошка ввода
CFont *m_pGivenFont;
CBrush m_ForeBrush;
public:
CEnterEditDialog(CWnd* pParent,int IDD ,LPCRECT lpRect,CFont *pGivenFont,COLORREF ForeRGB=0xffffffff,bool bSaveIfLosfFocus=false);
//{{AFX_DATA(CEnterEditDialog)
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEnterEditDialog)
public:
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CEnterEditDialog)
virtual void OnOK();
virtual void OnCancel();
virtual BOOL OnInitDialog();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnClose();
afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID);
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
файл EnterEditDialog.cpp
#include "stdafx.h"
#include "EnterEditDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEnterEditDialog dialog
CEnterEditDialog::CEnterEditDialog(CWnd* pParent,int IDD,LPCRECT lpRect,CFont *pGivenFont,COLORREF ForeRGB,bool bSaveIfLosfFocus):
CDialog(IDD,pParent)
{
//{{AFX_DATA_INIT(CEnterEditDialog)
//}}AFX_DATA_INIT
m_pParent=pParent;
m_Rect=*lpRect;
m_ForeRGB=ForeRGB;
m_ForeRGB=(ForeRGB!=0xffffffff?ForeRGB&0x00ffffff:0);
m_ForeBrush.CreateSolidBrush(ForeRGB!=0xffffffff?ForeRGB&0x00ffffff:0);
m_pGivenFont=pGivenFont;
m_csText="";
m_bCanCloseWhenWPCing=false;
m_TheFirstPaint=true;
m_bSaveIfLosfFocus=bSaveIfLosfFocus;
}
void CEnterEditDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEnterEditDialog)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CEnterEditDialog, CDialog)
//{{AFX_MSG_MAP(CEnterEditDialog)
ON_WM_CTLCOLOR()
ON_WM_CLOSE()
ON_WM_WINDOWPOSCHANGING()
ON_WM_ACTIVATE()
ON_WM_ACTIVATEAPP()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//удаляем все элементы с диалога
BOOL CALLBACK CEnterEditDialog::EnumChildProc(HWND hwnd,LPARAM lParam)
{
::DestroyWindow(hwnd);
return 1;
}
BOOL CEnterEditDialog::OnInitDialog()
{
CDialog::OnInitDialog();
ModifyStyle(WS_SYSMENU|WS_BORDER|WS_DLGFRAME|WS_THICKFRAME,0/*WS_VISIBLE|WS_CHILD|WS_POPUP|WS_CLIPSIBLINGS*/,0);
ModifyStyleEx(WS_EX_DLGMODALFRAME,0,0);
//удаляем все элементы с диалога на всякий случай (могли быть положены на ресурсе)
EnumChildWindows(m_hWnd,EnumChildProc,0);
//создаём едит
RECT tempR;//0,0,0,0
::memset(&tempR,0,sizeof(tempR));
if(!m_edit.Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,tempR,this,IDC_EDIT))return 0;
//задаём шрифт
if(m_pGivenFont)
{
if(m_pGivenFont->m_hObject)
{
m_edit.SetFont(m_pGivenFont);
}
}
//располагаем диалог там, где заказано
MoveWindow(&m_Rect,1);
//делаем едит размером в весь диалог
RECT r;
r.top=0;
r.bottom=m_Rect.bottom-m_Rect.top;
r.left=0;
r.right=m_Rect.right-m_Rect.left;
m_edit.MoveWindow(&r);
m_edit.SetWindowText(m_csText);
::PostMessage(m_edit.m_hWnd,EM_SETSEL,0,0);
return TRUE;
}
HBRUSH CEnterEditDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
//красим фон окошка едита
if(pWnd->GetDlgCtrlID()==IDC_EDIT)
{
if(!(m_ForeRGB&0xff000000))
{
pDC->SetBkColor(m_ForeRGB);
return (HBRUSH)m_ForeBrush;
}
}
return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}
void CEnterEditDialog::OnPaint()
{
CDialog::OnPaint();
if(m_TheFirstPaint)
{
m_TheFirstPaint=false;
m_bCanCloseWhenWPCing=true;
}
}
void CEnterEditDialog::OnClose()
{
m_bSaveIfLosfFocus=false;
//CDialog::OnClose();
}
void CEnterEditDialog::OnCancel()
{
m_bSaveIfLosfFocus=false;
CDialog::OnCancel();
}
void CEnterEditDialog::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
CDialog::OnWindowPosChanging(lpwndpos);
if(m_bCanCloseWhenWPCing)
{
if(m_bSaveIfLosfFocus)
{
OnOK();
}
else
{
EndDialog(IDCANCEL);
}
}
}
void CEnterEditDialog::OnOK()
{
//сохраняем введённый текст в m_csText
m_edit.GetWindowText(m_csText);
m_bCanCloseWhenWPCing=false;
CDialog::OnOK();
}
void CEnterEditDialog::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther, bMinimized);
if(pWndOther==this)
{
if(nState==WA_INACTIVE)
{
m_bCanCloseWhenWPCing=false;
}
if(nState==WA_ACTIVE || nState==WA_CLICKACTIVE)
{
m_bCanCloseWhenWPCing=false;
}
}
}
void CEnterEditDialog::OnActivateApp(BOOL bActive, DWORD dwThreadID)
{
CDialog::OnActivateApp(bActive, dwThreadID);
}
использование (функция выдрана из класса грида)
//открыть диалог для "редактирования текста ячейки"
//(на самом деле - открытие модального диалога с текстом-мембером)
void CGrid::EditCell(DWORD row,DWORD col,int idd_cell_edit_dialog,bool bSaveIfLosfFocus)
{
m_IDD_CELL_EDIT_DIALOG=idd_cell_edit_dialog;
if(!m_IDD_CELL_EDIT_DIALOG)return;
//открываем модальное окно ввода
RECT r;
if(!GetCellRect(r,row,col,true))return;
r.top++;
r.right--;
CEnterEditDialog Dlg(this,m_IDD_CELL_EDIT_DIALOG,&r,&m_fontTableFont,RGB(253,253,200),bSaveIfLosfFocus);
GetCellTextSTR_not_saved(row,col,&Dlg.m_csText);
if(IDOK==Dlg.DoModal())
{
SetCellTextSTR_not_saved(row,col,(const char*)Dlg.m_csText);
Invalidate(0);
}
}