新建一个对话框工程,添加WM_NCPAINT消息:
void CTestPopDlg::OnNcPaint()
{
// TODO: Add your message handler code here
CBitmap bmp;
bmp.LoadBitmap( IDB_BITMAP1 );
CWindowDC dc ( this );
CDC memDC;
memDC.CreateCompatibleDC( &dc ); CRect rect;
GetWindowRect( &rect );
memDC.SelectObject( &bmp );
dc.StretchBlt( 0, 0, rect.Width(), 25, &memDC, 0, 0, 10, 25, SRCCOPY );
// Do not call CDialog::OnNcPaint() for painting messages
}
再对话框中拖一个Button,响应函数为:
void CTestPopDlg::OnButton1()
{
// TODO: Add your control notification handler code here
AfxMessageBox( "a" );
}
现在的问题是:
1、按下Button,当弹出MessageBox时,标题栏的位置就消失了,这时移动MessageBox,位图会重新出现,显示是在MessageBox弹出时没有重绘。请问这个问题
怎么解决,
2、当执行程序时,如果鼠标在最小化、最大化、关闭按钮处按下,然后在其它位置释放,这时相应的按钮就会出现,怎么使用它们不出现,并且还可以有效(即按下最大化时还可以使窗口最大化,因为左边的系统菜单有效,但系统菜单的图标并不会出现)
void CTestPopDlg::OnNcPaint()
{
// TODO: Add your message handler code here
CBitmap bmp;
bmp.LoadBitmap( IDB_BITMAP1 );
CWindowDC dc ( this );
CDC memDC;
memDC.CreateCompatibleDC( &dc ); CRect rect;
GetWindowRect( &rect );
memDC.SelectObject( &bmp );
dc.StretchBlt( 0, 0, rect.Width(), 25, &memDC, 0, 0, 10, 25, SRCCOPY );
// Do not call CDialog::OnNcPaint() for painting messages
}
再对话框中拖一个Button,响应函数为:
void CTestPopDlg::OnButton1()
{
// TODO: Add your control notification handler code here
AfxMessageBox( "a" );
}
现在的问题是:
1、按下Button,当弹出MessageBox时,标题栏的位置就消失了,这时移动MessageBox,位图会重新出现,显示是在MessageBox弹出时没有重绘。请问这个问题
怎么解决,
2、当执行程序时,如果鼠标在最小化、最大化、关闭按钮处按下,然后在其它位置释放,这时相应的按钮就会出现,怎么使用它们不出现,并且还可以有效(即按下最大化时还可以使窗口最大化,因为左边的系统菜单有效,但系统菜单的图标并不会出现)
解决方案 »
- VC如何实现手机USB连接,操作手机内数据
- CCombo Box逐行读、添加数据有点慢,能不能一下把所有数据添加进行?
- 请教MSN messenge聊天消息的获取
- 把一个数字(INT)变成字符(CHAR) ,如何做.
- 请问在XP下可否安装VC60,为什么我总是安装不成功呢,但在98下就没问题
- 急!请问各位,如何让按钮失效?!
- 调用vbs脚本时如何传递参数?
- 菜鸟问题,在MFC中如何添加CheckListBox
- 吉林大学的Windows程序设计视频教程怎么样,有没有看过的?
- 如何访问对方电脑WINDOWS的注册表,并更改指定项。急急急,请高手赐教!!!
- 急问!CStringW为什么不能在VC6.0下识别
- 存储过程可以返回结果集,怎么读取这些结果集的数据,
问题2: 可以通过使OnNcHitTest返回HTCLIENT来解决, 但是也不能通过他来移动窗口了
1、按下Button,当弹出MessageBox时,标题栏的位置就消失了,这时移动MessageBox,位图会重新出现,显示是在MessageBox弹出时没有重绘。请问这个问题
怎么解决,
这个问题是因为AfxMessageBox有自己的消息循环,系统帮忙代办了你的Dialog的Nc Paint动作。只要在Afxmessagebox之前调用LockWindowUpdate()禁止系统重画,在AfxMessageBox之后调UnlockWindowUpdate()即可。但是这样会出现重绘问题。我的建议还是你不要用系统的captionbar,直接自己绘制。2、当执行程序时,如果鼠标在最小化、最大化、关闭按钮处按下,然后在其它位置释放,这时相应的按钮就会出现,怎么使用它们不出现,并且还可以有效(即按下最大化时还可以使窗口最大化,因为左边的系统菜单有效,但系统菜单的图标并不会出现)
这个好像没有办法。这些按钮是窗口风格决定的。还是老办法,自己画按钮。
void CResizableMiniDockFrameWnd::OnNcPaint()
{
CWindowDC dc(this); CRect rectClient(0,0,0,0);
GetClientRect(rectClient);
CRect rectWindow(0,0,0,0);
GetWindowRect(rectWindow);
ScreenToClient(rectWindow);
rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
dc.ExcludeClipRect(rectClient);
rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
CSize sizeFrame(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
CSize sizeBorder(GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
CSize sizeSmIcon(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
CMemoryDC dcMemory;
dcMemory.Create(&dc, rectWindow);
//±ß¿ò
dcMemory.DrawEdge(&rectWindow, EDGE_RAISED, BF_RECT);
CRect rectCaption(rectWindow);
rectCaption.DeflateRect(sizeFrame.cx, sizeFrame.cy);
rectCaption.bottom = rectCaption.top + sizeSmIcon.cy - sizeBorder.cy;
//±êÌâÀ¸µ×É«
BOOL bGradient = FALSE;
::SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &bGradient, 0);
COLORREF clrLeft = ::GetSysColor(COLOR_ACTIVECAPTION);
COLORREF clrRight = ::GetSysColor(COLOR_GRADIENTACTIVECAPTION);
COLORREF clrGray = ::GetSysColor(COLOR_INACTIVECAPTION);
if(bGradient && m_bActive)
{
int nShift = 6;
int nSteps = 1 << nShift;
for(int i=0; i<nSteps; ++i)
{
int nRed = (GetRValue(clrLeft) * (nSteps - i) + GetRValue(clrRight) * i) >> nShift;
int nGreen = (GetGValue(clrLeft) * (nSteps - i) + GetGValue(clrRight) * i) >> nShift;
int nBlue = (GetBValue(clrLeft) * (nSteps - i) + GetBValue(clrRight) * i) >> nShift;
CRect rect(rectCaption);
rect.left = rectCaption.left +((i * rectCaption.Width()) >> nShift);
rect.right = rectCaption.left +(((i + 1) * rectCaption.Width()) >> nShift);
if(rect.Width() > 0)
{
dcMemory.FillSolidRect(rect, RGB(nRed, nGreen, nBlue));
}
}
}
else
{
dcMemory.FillSolidRect(&rectCaption, m_bActive ? clrLeft:clrGray);
}
LOGFONT fontCaption = {0};
::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &fontCaption, 0);
fontCaption.lfWeight = FW_BOLD;
HFONT hCaptionFont = CreateFontIndirect(&fontCaption);
HGDIOBJ hOldFont = dcMemory.SelectObject(hCaptionFont);
dcMemory.SetTextColor(::GetSysColor(COLOR_CAPTIONTEXT));
dcMemory.SetBkMode(TRANSPARENT);
CString strCaption(_T(""));
GetWindowText(strCaption);
if(strCaption.IsEmpty())
{
strCaption = _T("ToolBar");
}
CSize sizeText(dcMemory.GetTextExtent(strCaption));
//Êä³öÎı¾(ÓҶ˿۳ýButtonËùÕ¼µÄλÖÃ)
CRect rectText(rectCaption);
rectText.left += sizeBorder.cx * 2;
rectText.right -= sizeSmIcon.cx * 2 + sizeBorder.cx;
dcMemory.DrawText(strCaption, &rectText, DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS);
dcMemory.SelectObject(hOldFont);
DeleteObject(hCaptionFont);
DrawButton(&dcMemory, rectCaption);
dcMemory.Flush();
}
那篇文章我很早就看过,我现在想做的是一个换肤的DLL,我以前也是把标题栏去掉,想怎么做就怎么做,不过现在由于每个程序都可能用到我的DLL,所有不能这样做,因为这做做了所有的程序的标题栏都一样了,因为有的标题栏上没有最大化和最小化按钮,有的没有系统菜单,并且这样做了,系统菜单就没有了,我通过GetSystemMenu,然后再弹出来,是可以显示,但不起作用。这个问题郁闷我很久了另外LockWindowUpdate()我试了,确实可以实现,不过这只能要求客户端调用了,我想在我的SkinDLL中调用。客户端只要一个初始化皮肤就好那种。不过还是非常感谢你。
前面说过,我自绘过CMiniDockFrameWnd,当时是取消MFS_SYSMENU来取消那个关闭按钮,然后自己画了一个上去。不过Dialog我还真不知道怎么去掉,我想,实在不行就去掉sysmenu风格,然后自己画那个几个按钮。