子窗口最小化状态自绘制的问题

狼异族 2019-04-24 09:23:30
创建一个弹出子窗口 只带有 WS_POPUP |WS_VISIBLE 属性, 自己绘制了最小化和关闭按钮,但是窗口最小化之后,在切换到别的程序,再切回来时, 这个子窗口又自动还原了, 还有在OnNCPaint绘制子窗口的最小化状态时,仅刚开始有效,如果焦点切换到别的程序时, 自己绘制的效果又没了

最小化状态的自绘制效果最小化状态的原始效果
...全文
588 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2019-06-02
  • 打赏
  • 举报
回复
统一起来 !

void CMyMdi::OnNcPaint() // NC SelfDraw
{
// TODO: Add your message handler code here
CSize sizeButton(25,26);//GetSystemMetrics(SM_CXSIZE),GetSystemMetrics(SM_CYSIZE));// 27,27
CWindowDC dc(this);
CRect rect,rt;
GetWindowRect(rect);
rect.OffsetRect(-rect.left,-rect.top);
// 3 pixel board
dc.Draw3dRect(&rect,RGB(210,208,200),RGB(64,64,64));
rect.DeflateRect(1,1);//
dc.Draw3dRect(&rect,RGB(255,255,255),RGB(128,128,128));
rect.DeflateRect(1,1);//
dc.Draw3dRect(&rect,RGB(210,208,200),RGB(210,208,200));
// background
rect.bottom = GetSystemMetrics(SM_CYCAPTION);// 31
DrawColorTitle(rect,RGB(0,0,255),RGB(220,220,255),&dc);
// draw icon 16*16 -> 24*24
DrawIconEx(dc.m_hDC,rect.left+2,rect.top+2,m_hIcon,24,24,0,0,DI_IMAGE);
// text
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(255,255,255));
if(IsIconic())
{
dc.TextOut(32,6,"Min..",5);
}
else
{
dc.TextOut(32,6,"MyMdi",5);
}
// button size
CRect rc;
rc.right = rect.right-2;
rc.left = rc.right - sizeButton.cx;
rc.top = rect.top+3;
rc.bottom = sizeButton.cy+3;
// draw button
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONCLOSE);
rc.OffsetRect(-sizeButton.cx-2,0);
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONMAX|DFCS_INACTIVE);
rc.OffsetRect(-sizeButton.cx,0);
if(IsIconic())
{
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONRESTORE);
}
else
{
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONMIN);
}
// CMDIFrameWnd::OnNcPaint();// for painting messages
}
狼异族 2019-06-02
  • 打赏
  • 举报
回复
引用 14 楼 狼异族 的回复:
[quote=引用 13 楼 schlafenhamster 的回复:] dc.TextOut(34,4,"欢迎",4); 加大 34
不是这个问题 是中间的“测试窗口”以及背景色都是系统自己绘制的 而且还是在OnNcPaint之后 不知道怎么去掉[/quote] 这个问题解决了 在OnNcActive返回TRUE 就行了
狼异族 2019-06-02
  • 打赏
  • 举报
回复
引用 13 楼 schlafenhamster 的回复:
dc.TextOut(34,4,"欢迎",4); 加大 34
不是这个问题 是中间的“测试窗口”以及背景色都是系统自己绘制的 而且还是在OnNcPaint之后 不知道怎么去掉
schlafenhamster 2019-06-02
  • 打赏
  • 举报
回复
dc.TextOut(34,4,"欢迎",4);
加大 34
狼异族 2019-06-01
  • 打赏
  • 举报
回复
引用 10 楼 schlafenhamster 的回复:
给个例子
完全照抄了你的代码 发现边框可以绘制 但是中间内容部分被覆盖了 窗口还需要设置别的什么属性吗?
schlafenhamster 2019-04-29
  • 打赏
  • 举报
回复
改了点
// draw button
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONCLOSE);
rc.OffsetRect(-sizeButton.cx-2,0);
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONMAX|DFCS_INACTIVE);
rc.OffsetRect(-sizeButton.cx,0);
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONRESTORE);
schlafenhamster 2019-04-29
  • 打赏
  • 举报
回复
给个例子

//
void DrawColorTitle(CRect rect, COLORREF col1, COLORREF col2,CDC* pDC)
{
int cx = rect.Width();
int red = GetRValue(col2) - GetRValue(col1);
int green = GetGValue(col2) - GetGValue(col1);
int blue = GetBValue(col2) - GetBValue(col1);
int i = 0;
while (i < cx)
{
int r = GetRValue(col1) + i*red / cx;
int g = GetGValue(col1) + i*green / cx;
int b = GetBValue(col1) + i*blue / cx;
CPen pen(PS_SOLID,1,RGB(r,g,b));
pDC->SelectObject(pen);
pDC->MoveTo(i,0);
pDC->LineTo(i,rect.bottom);
++i;
}
}
//
void CMyMdi::OnNcPaint()
{
// TODO: Add your message handler code here
if(IsIconic())
{
CSize sizeButton(GetSystemMetrics(SM_CXSIZE),GetSystemMetrics(SM_CYSIZE));// 27,27
sizeButton.cx-=1;
sizeButton.cy-=1;
//
CWindowDC dc(this);
CRect rect,rt;
GetWindowRect(rect);
rect.OffsetRect(-rect.left,-rect.top);
// 3 pixel board
dc.Draw3dRect(&rect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DFACE));
rect.DeflateRect(1,1);//
dc.Draw3dRect(&rect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
rect.DeflateRect(1,1);//
dc.Draw3dRect(&rect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
rect.bottom = 30;
// background
DrawColorTitle(rect,RGB(0,0,255),RGB(200,200,255),&dc);
// draw icon 16*16 -> 26*26
HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
DrawIconEx(dc.m_hDC,4,2,hIcon,26,26,0,0,DI_IMAGE);
// text
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(255,255,255));
dc.TextOut(34,4,"欢迎",4);
// button size
CRect rc;
rc.right = rect.Width();
rc.left = rc.right - sizeButton.cx;
rc.top = rect.top+3;
rc.bottom = sizeButton.cy+3;
// draw button
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONCLOSE);
rc.OffsetRect(-sizeButton.cx-2,0);
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONMAX);
rc.OffsetRect(-sizeButton.cx,0);
dc.DrawFrameControl(rc,DFC_CAPTION,DFCS_CAPTIONMIN);
return;
}
//
CMDIFrameWnd::OnNcPaint();// for painting messages
}

狼异族 2019-04-24
  • 打赏
  • 举报
回复
【在切换到别的程序,再切回来时, 这个子窗口又自动还原了】 还有这个问题怎么解决 如果使用系统自带的标题栏就不会有这个问题
schlafenhamster 2019-04-24
  • 打赏
  • 举报
回复
if (IsIconic())//m_hWnd)) 不进入 !
狼异族 2019-04-24
  • 打赏
  • 举报
回复
引用 4 楼 schlafenhamster 的回复:
void CWndMainView::OnNcPaint() 有没有响应 ?
有响应 但是程序焦点消失会自动变成原始效果
狼异族 2019-04-24
  • 打赏
  • 举报
回复
引用 3 楼 zgl7903 的回复:
IsIconic 这个判断逻辑是不是反了?
这个没问题 只是在窗口最小化状态下才在这绘制 正常状态在onpaint绘制
schlafenhamster 2019-04-24
  • 打赏
  • 举报
回复
void CWndMainView::OnNcPaint() 有没有响应 ?
zgl7903 2019-04-24
  • 打赏
  • 举报
回复
IsIconic 这个判断逻辑是不是反了?
狼异族 2019-04-24
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
个人经验: 使用无边框的窗口, 在客户区做自绘可以排除很多麻烦
没有边框 正常状态整个窗口只有客户区 就是最小化的时候不知道怎么处理了 处理的效果很不好 ONPaint的代码
void CWndMainView::OnNcPaint() 
{
	// TODO: Add your message handler code here
	if (::IsIconic(m_hWnd))
	{
		CWindowDC dc(this);
		CRect rect;
		GetWindowRect(&rect);
		ScreenToClient(&rect);

		dc.FillSolidRect(rect, RGB(255, 255, 255));

		Graphics graphics(dc.GetSafeHdc());
		graphics.SetSmoothingMode(SmoothingModeHighQuality);

		CSize sizeBtn(38, 30);	
		Image* pImage		= GetImageByID(IDR_PNG_WINDOW_CLOSE);
		if (NULL != pImage)
		{
			sizeBtn.cx		= pImage->GetWidth();
			sizeBtn.cy		= pImage->GetHeight()/2;
		}
		m_btnClose.rcBtn.right	= rect.right - SCALEDPI(5);
		m_btnClose.rcBtn.left	= m_btnClose.rcBtn.right - sizeBtn.cx;
		m_btnClose.rcBtn.top	= (rect.top + rect.bottom - sizeBtn.cy)/2;
		m_btnClose.rcBtn.bottom	= m_btnClose.rcBtn.top + sizeBtn.cy;
		
		::SetRectEmpty(&m_btnMinimize.rcBtn);
		m_btnRestore.rcBtn			= m_btnClose.rcBtn;
		m_btnRestore.rcBtn.right	= m_btnClose.rcBtn.left - SCALEDPI(5);
		m_btnRestore.rcBtn.left		= m_btnRestore.rcBtn.right - sizeBtn.cx;	

		DrawButton(graphics, m_btnClose, GetImageByID(IDR_PNG_WINDOW_CLOSE));
		DrawButton(graphics, m_btnRestore, GetImageByID(IDR_PNG_WINDOW_RESTORE));
	}
	
	// Do not call CWnd::OnNcPaint() for painting messages
}
zgl7903 2019-04-24
  • 打赏
  • 举报
回复
个人经验: 使用无边框的窗口, 在客户区做自绘可以排除很多麻烦
zgl7903 2019-04-24
  • 打赏
  • 举报
回复
试试处理 WM_NCACTIVATE 返回TRUE, 不要进入默认调用

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧