컨트롤의 상태와 텍스트에 관계없이 항상 컨트롤 창에 아이콘이 표시된 MFC에서 검색 편집 컨트롤을 만들려고합니다. 몇 년 전에 이런 식으로 글을 썼지 만 잘 작동했지만 코드는 더 이상 Windows 7 이상에서 작동하지 않습니다. (아마도 Vista 일 수도 있지만 시도하지 않았습니다.) 그러면 컨트롤에 표시된 이미지가 입력 영역과 겹치게됩니다 (아래 그림 참조).편집 컨트롤의 검색 아이콘이 입력 영역과 겹침
코드 뒤에 아이디어 :
- 이 클래스 (즉의 OnPaint에 그림을 처리)
- 이 아이콘이 오른쪽에 표시되고 편집 영역의 크기에 따라 축소되어
CEdit
에서 유래 한 아이콘 - 크기 조정은 한 줄 편집과 여러 줄 편집의 경우 다르게 수행됩니다. 한 줄의 경우 SetMargins으로 전화를 걸고 여러 줄을 편집 할 경우 SetRect으로 전화합니다. 합니다 (
void CSymbolEdit::RecalcLayout() { int width = GetSystemMetrics(SM_CXSMICON); if(m_hSymbolIcon) { if (GetStyle() & ES_MULTILINE) { CRect editRect; GetRect(&editRect); editRect.right -= (width + 6); SetRect(&editRect); } else { DWORD dwMargins = GetMargins(); SetMargins(LOWORD(dwMargins), width + 6); } } }
다음 이미지를 표시하고 하나의 라인에 대한 문제가 편집 :
- 이 편집 리사이징은
PreSubclassWindow()
,OnSize()
및OnSetFont()
이 편집 입력 크기가 적용되는 방법이다에서인가 더 좋은보기를 위해 이미지가 확대되었습니다). 노란색 배경은 실제 코드에서 강조 표시하기위한 것이며 시스템 색상을 사용하고 있습니다. 한 줄 편집에 텍스트가 있고 입력이 있으면 왼쪽 이미지가 칠해집니다. SetRect
이 서식 지정 사각형을 올바르게 설정하는 여러 줄 편집에서는이 문제가 발생하지 않습니다.
이 나는 이미지가 표시되고 편집의 영역을 제거 ExcludeClipRect를 사용하여 시도했다.
CRect rc;
GetClientRect(rc);
CPaintDC dc(this);
ExcludeClipRect(dc.m_hDC, rc.right - width - 6, rc.top, rc.right, rc.bottom);
DWORD dwMargins = GetMargins();
SetMargins(LOWORD(dwMargins), width + 6);
결과에 아무런 영향을 미치지 않는 것으로 보입니다.
참고로,이 방법은 몇 년 전에 작성되었으며 Windows XP에서 제대로 작동하는 데 사용되었지만 더 이상 올바르지 않습니다.
void CSymbolEdit::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
// Clearing the background
dc.FillSolidRect(rect, GetSysColor(COLOR_WINDOW));
DWORD dwMargins = GetMargins();
if(m_hSymbolIcon)
{
// Drawing the icon
int width = GetSystemMetrics(SM_CXSMICON);
int height = GetSystemMetrics(SM_CYSMICON);
::DrawIconEx(
dc.m_hDC,
rect.right - width - 1,
1,
m_hSymbolIcon,
width,
height,
0,
NULL,
DI_NORMAL);
rect.left += LOWORD(dwMargins) + 1;
rect.right -= (width + 7);
}
else
{
rect.left += (LOWORD(dwMargins) + 1);
rect.right -= (HIWORD(dwMargins) + 1);
}
CString text;
GetWindowText(text);
CFont* oldFont = NULL;
rect.top += 1;
if(text.GetLength() == 0)
{
if(this != GetFocus() && m_strPromptText.GetLength() > 0)
{
oldFont = dc.SelectObject(&m_fontPrompt);
COLORREF color = dc.GetTextColor();
dc.SetTextColor(m_colorPromptText);
dc.DrawText(m_strPromptText, rect, DT_LEFT|DT_SINGLELINE|DT_EDITCONTROL);
dc.SetTextColor(color);
dc.SelectObject(oldFont);
}
}
else
{
if(GetStyle() & ES_MULTILINE)
CEdit::OnPaint();
else
{
oldFont = dc.SelectObject(GetFont());
dc.DrawText(text, rect, DT_SINGLELINE | DT_INTERNAL | DT_EDITCONTROL);
dc.SelectObject(oldFont);
}
}
}
비슷한 편집 컨트롤의 다른 구현을 살펴 봤는데 모두 동일한 오류가 발생했습니다.
분명히 질문은 컨트롤의 입력 영역에서 이미지 영역을 제외시키는 것입니다. 내가 무슨 일이 일어나고 있는지 생각
'OnPaint' 오버라이드가 Edit 컨트롤의 페인트 루틴과 싸우고 있습니다. 'CPaintDC'를 사용하여 컨트롤을 수동으로 페인트합니다. 때로는'CEdit :: OnPaint'를 호출하고, 다시 CPaintDC를 호출하고 클라이언트 영역을 다시 칠하는 기본 처리를합니다. Edit 컨트롤의 초점이 맞지 않을 때 또는 페인트 메시지가 수신되면이 작업은 실패합니다. –
'CEdit :: OnPaint()'는 다중 편집에 대해서만 호출됩니다. 이것은 내 관심사가 아닙니다. 단일 줄 편집 컨트롤 만 사용하고 있습니다. 이 경우 경계를 올바르게 설정했기 때문에 여러 줄 편집을 언급했습니다. –
'CWnd :: OnCtlColor()'를 오버라이드하고 거기에서'ExcludeClipRect()'를 호출하면 어떨까요? 빠른 테스트와 함께 여기서 제대로 작동하지만 MFC가없는 것 같습니다. 자신의 물건을 보여주기 위해'OnPaint()'에서 다시 클리핑을 변경해야 할 수도 있습니다. – isanae