急,急,急,关于自画窗口标题条的问题,请高手帮忙... ... 在线中,立即给分 好像要先实现WM_NCHITTEST消息,在那里是标题条的返回HTCAPTION,其他的再调用DefWindowProc(...)就可以了 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 跟WM_NCHITTEST的关系不大, 我在CMDIFrameWnd::OnNcLButtonDown(nHitTest, point);后加了一句 OnNcPaint(); //再将标题条画一次结果,当按下鼠标来拖动窗口时, OnNcPaint()直到拖动结束后才会被执行,很显然在DefFrameProc中对WM_NCLUBTTONDOWN的响应中有一个message loop来处理窗口的拖动 所以,我想我的这个问题只有两个方法来解决: 1 找出控制DefFrameProc不重画按钮的方法. 2 完全重写导致按钮重画的几个消息,如WM_NCLUBUTTONDOWN,自己来处理窗口的行为,当然,这就相当麻烦了. 哪位知道第一种解决方法的高手,请不吝赐教 怎么今天都在自绘这东西呵呵http://www.codeguru.com/dialog/DrawOnTitleBar.shtml不过是个dialog的。。应该差不多 2 black_fox(black_fox): 请仔细看看我的问题, 是只在MDI工程下才有的问题. 我自己画了SDI,肯定没你那种问题如果在PreCreateWindow(CREATESTRUCT& cs)中加上 cs.style &= ~WS_SYSMENU;让他没有那些按钮,它们还会跑出来吓人吗? 2 Flysnow(飞雪): 你的方法我没试,不知是否有效. 但对我来说是无效的,因我一定是要有系统菜单的. 处理WM_SYSCOMMAND,SC_MOVE再不行就用spy++看看按下时还有什么消息,消息的参数是什么。 2 hello008(paladin):其它的消息我都截取试过,对以上我所说的现象都没影响,重画标题条按钮的代码就在WM_NCLBUTTONDOWN的响应中 2 chief(大副) WS_SYSMENU只是把上面的蓝色部份全清空,下面的菜单还有再说点图标的菜单可以自己再响应嘛,这应该都一样,反正Windows到了我们手里想叫它什么样,就什么样 2 Flysnow(飞雪)问题在这里,在去掉WM_SYSMENU后,系统任务栏上的窗口按钮将没有图标,而这是不行的 重画caption的程序处理了很多消息,并非这么几个。www.programsalon.com里有三个重画caption的程序,但没有一个是重画按钮的,其中一个mdi程序是画childframe的,处理了WM_SYSCOMMAND消息。 哦,我明白了,没ICON也很漂亮啊 哦,我明白了,没ICON也很漂亮啊 2 hello008(paladin):我知道有很多个,但使我头疼的就是鼠标左右键点击CAPTION导致系统按钮重画的问题,所以我就只提出这个. 2 ttzzgg_80713(我要吃了你) :谢谢, [email protected], 问题解决,立即给分 标题栏的重画与WM_NCACTIVE消息有关。 afx_msg BOOL OnNcActivate( BOOL bActive );MFC根据bActive的值来确定标题栏的激活或非激活状态,并画出不同状态下的标题栏。 响应WM_NCACTIVE消息,在OnNcActivate中调用自己绘制标题拦的函数。如果标题栏有激活和不激活两种状态,根据bActive的值调用不同的绘制函数。BOOL CFrameWnd::OnNcActivate(BOOL bActive)函数有bActive的使用示例。 2 assert001(true) : 当窗口本身已是激活时,再在标题条上点鼠标是不会发出WM_NCACTIVATE消息的, 我这个问题的关键在于,当鼠标在标题上点击或点击拖动时,会引起系统按钮的重画,(仅仅只重画系统按钮哟, 所以此时没有WM_NCPAINT), 而且当点击一次右键出来系统菜单之后,再来点左键或拖动窗口,却又没有上述情况了, 所以我就想问一下, 有没有可以控制到任何时候在标题条上点左键都不会重画系统按钮的方法. chief(大副) : 例程发出。有任何问题。可以email我 2 ttzzgg_80713(我要吃了你)TKS,我来看看 2 ttzzgg_80713(我要吃了你) 没有收到也,再帮忙发一记遍吧, TKS 我一般都是去掉系统的标题条,然后自己用CDialogBar做一个标题条 2 AloneWolf(孤狼) :天,那要自己做的事情太多了,开发时间不允许 void C****::OnNcPaint() { // TODO: Add your message handler code here Default(); //画DrawCaption // Do not call CDialog::OnNcPaint() for painting messages} 按钮对应着SYSMENU,所以应该是WM_SYSMENU消息。 2 ttzzgg_80713(我要吃了你) email未收到,请再发一遍,tks 同意silverwgy(yiyi) 的意见!!在响应WM_NCHITTEST的时候不要返回SC_CLOSE等,而是返回自己的定义,这样Windows就不会响应这写消息了!!一切不就OK了吗,自己根据返回值画! [email protected]: 今天我到我的信籍看了一下。该email被退回了。换个地址吧。我再发一次。 2 ttzzgg_80713(我要吃了你): 你的程序我看了, 确实是画CAPTION的. 但对于我的问题并无多大帮助, 因我的问题只是针对MDI窗口的,在SDI和对话框的情况下都无此问题. 还是谢谢你,若还是没人有办法解决的话, 我会放分的. 2 ttzzgg_80713(我要吃了你): 能不能给小弟再发一份??:-) to chief (大副):你要做的东西太复杂,我只帮你解决鼠标点击标题栏的问题。 你试试看行不行void CMainFrame::OnNcPaint() { if( !m_bExeSysClose ) CMDIFrameWnd::OnNcPaint(); CDC* pDC = GetWindowDC(); CRect r; GetCaptionRect(r); pDC->FillSolidRect( r.left, r.top, r.Width(), r.Height(), RGB(255,0,0) ); ReleaseDC( pDC ); if( m_bExeSysClose ) CMDIFrameWnd::OnNcPaint(); }void CMainFrame::GetCaptionRect(CRect &r){long lStyle = GetStyle(); int nBorder=0, nButton=0; if( lStyle & WS_BORDER ) nBorder = 1;// if( lStyle & WS_SYSMENU )// nButton = 1;// if( ( lStyle & WS_MAXIMIZEBOX ) || ( lStyle & WS_MINIMIZEBOX ) )// nButton += 2; NONCLIENTMETRICS sNCM; sNCM.cbSize = sizeof(sNCM); SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof(sNCM), &sNCM, 0 ); CRect rWindow; GetWindowRect(&rWindow); r.left = rWindow.left + nBorder*sNCM.iBorderWidth + sNCM.iCaptionWidth + 4; r.top = rWindow.top + nBorder*sNCM.iBorderWidth + 2; r.right = rWindow.right - nBorder*sNCM.iBorderWidth - sNCM.iCaptionWidth*nButton - 3; r.bottom = r.top + sNCM.iCaptionHeight; r -= rWindow.TopLeft();}void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) { if( nID == SC_CLOSE ) m_bClose = TRUE; if( nID = SC_MOVE ) { if( !m_bClose ) { m_bExeSysClose = TRUE; OnNcPaint(); m_bExeSysClose = FALSE; } } CMDIFrameWnd::OnSysCommand(nID, lParam); }来不及跟你解释了,byebye 小弟现也为这事头疼,我问了半天没人回,我现在有一个解决办法:LockWindowUpdate();UnLockWindowUpdate;例如:void CMainFrame::OnNcLbuttonDown(flags,point){ LockWindowUpdate(); CMDIFrameWnd::OnNcLButtonDown(); UnLockWindowUpdate();}这个要试试:void CMainFrame::OnSetCursor(){ LockWindowUpdate(); CMDIFrameWnd::OnSetCursor(); UnLockWindowUpdate();}我发觉问提地关键是如何不让WINDOWS Update 我要处理的地放试试 JPEG2000压缩算法 中国开发者2004广州聚会 杂录 MFC中,我该怎样取得发出消息的窗口ID? 作为回报,zhdleo来领分,500 非常硬件问题:系统主板上有个8254可编程计时芯片,查到它的地址为0x40-43,欲对其读写,可是…… 如何在VC++中嵌入汇编语言 如何改变对话框的背景颜色? 一个函数的参数声明只有一个类型 求调用方法 求救:关于WinSock编程? 学习VC要哪些基础? 菜鸟问题:VC写的dll在delphi中的怎样调用 简单问题:系统如何通过.h文件找到这个.h文件的实现文件?
我在CMDIFrameWnd::OnNcLButtonDown(nHitTest, point);后加了一句
OnNcPaint(); //再将标题条画一次
结果,当按下鼠标来拖动窗口时, OnNcPaint()直到拖动结束后才会被执行,很显然在DefFrameProc中对WM_NCLUBTTONDOWN的响应中有一个message loop来处理窗口的拖动 所以,我想我的这个问题只有两个方法来解决:
1 找出控制DefFrameProc不重画按钮的方法.
2 完全重写导致按钮重画的几个消息,如WM_NCLUBUTTONDOWN,自己来处理窗口的行为,当然,这就相当麻烦了. 哪位知道第一种解决方法的高手,请不吝赐教
http://www.codeguru.com/dialog/DrawOnTitleBar.shtml
不过是个dialog的。。应该差不多
请仔细看看我的问题, 是只在MDI工程下才有的问题.
你的方法我没试,不知是否有效. 但对我来说是无效的,因我一定是要有系统菜单的.
再不行就用spy++看看按下时还有什么消息,消息的参数是什么。
其它的消息我都截取试过,对以上我所说的现象都没影响,重画标题条按钮的代码就在WM_NCLBUTTONDOWN的响应中
www.programsalon.com里有三个重画caption的程序,但没有一个是重画按钮的,其中一个mdi程序是画childframe的,处理了WM_SYSCOMMAND消息。
我知道有很多个,但使我头疼的就是鼠标左右键点击CAPTION导致系统按钮重画的问题,所以我就只提出这个. 2 ttzzgg_80713(我要吃了你) :谢谢, [email protected], 问题解决,立即给分
afx_msg BOOL OnNcActivate( BOOL bActive );
MFC根据bActive的值来确定标题栏的激活或非激活状态,并画出不同状态下的标题栏。
响应WM_NCACTIVE消息,在OnNcActivate中调用自己绘制标题拦的函数。如果标题栏有激活和不激活两种状态,根据bActive的值调用不同的绘制函数。BOOL CFrameWnd::OnNcActivate(BOOL bActive)函数有bActive的使用示例。
当窗口本身已是激活时,再在标题条上点鼠标是不会发出WM_NCACTIVATE消息的,
我这个问题的关键在于,当鼠标在标题上点击或点击拖动时,会引起系统按钮的重画,(仅仅只重画系统按钮哟, 所以此时没有WM_NCPAINT),
而且当点击一次右键出来系统菜单之后,再来点左键或拖动窗口,却又没有上述情况了, 所以我就想问一下, 有没有可以控制到任何时候在标题条上点左键都不会重画系统按钮的方法.
例程发出。有任何问题。可以email我
TKS,我来看看
天,那要自己做的事情太多了,开发时间不允许
{
// TODO: Add your message handler code here
Default();
//画DrawCaption
// Do not call CDialog::OnNcPaint() for painting messages
}
这样Windows就不会响应这写消息了!!
一切不就OK了吗,自己根据返回值画!
今天我到我的信籍看了一下。该email被退回了。换个地址吧。我再发一次。
你的程序我看了, 确实是画CAPTION的.
但对于我的问题并无多大帮助, 因我的问题只是针对MDI窗口的,在SDI和对话框的情况下都无此问题.
还是谢谢你,若还是没人有办法解决的话, 我会放分的.
能不能给小弟再发一份??:-)
void CMainFrame::OnNcPaint()
{
if( !m_bExeSysClose )
CMDIFrameWnd::OnNcPaint();
CDC* pDC = GetWindowDC(); CRect r;
GetCaptionRect(r); pDC->FillSolidRect( r.left, r.top, r.Width(), r.Height(), RGB(255,0,0) ); ReleaseDC( pDC );
if( m_bExeSysClose )
CMDIFrameWnd::OnNcPaint();
}void CMainFrame::GetCaptionRect(CRect &r)
{
long lStyle = GetStyle();
int nBorder=0, nButton=0;
if( lStyle & WS_BORDER )
nBorder = 1;
// if( lStyle & WS_SYSMENU )
// nButton = 1;
// if( ( lStyle & WS_MAXIMIZEBOX ) || ( lStyle & WS_MINIMIZEBOX ) )
// nButton += 2; NONCLIENTMETRICS sNCM;
sNCM.cbSize = sizeof(sNCM);
SystemParametersInfo( SPI_GETNONCLIENTMETRICS,
sizeof(sNCM), &sNCM, 0 );
CRect rWindow;
GetWindowRect(&rWindow);
r.left = rWindow.left + nBorder*sNCM.iBorderWidth + sNCM.iCaptionWidth + 4;
r.top = rWindow.top + nBorder*sNCM.iBorderWidth + 2;
r.right = rWindow.right - nBorder*sNCM.iBorderWidth - sNCM.iCaptionWidth*nButton - 3;
r.bottom = r.top + sNCM.iCaptionHeight;
r -= rWindow.TopLeft();
}void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
if( nID == SC_CLOSE )
m_bClose = TRUE;
if( nID = SC_MOVE )
{
if( !m_bClose )
{
m_bExeSysClose = TRUE;
OnNcPaint();
m_bExeSysClose = FALSE;
}
}
CMDIFrameWnd::OnSysCommand(nID, lParam);
}来不及跟你解释了,byebye
UnLockWindowUpdate;例如:
void CMainFrame::OnNcLbuttonDown(flags,point)
{
LockWindowUpdate();
CMDIFrameWnd::OnNcLButtonDown();
UnLockWindowUpdate();
}
这个要试试:
void CMainFrame::OnSetCursor()
{
LockWindowUpdate();
CMDIFrameWnd::OnSetCursor();
UnLockWindowUpdate();
}我发觉问提地关键是如何不让WINDOWS Update 我要处理的地放
试试