问题描述
我现在使用TextOut进行字符输出,发现看不到输出字符显示,找不到原因,下面是我的部分代码:voidCcalendar::feastdate(CPaintDC&dc){#defineDISP_X15#defineDISP_Y210CFontfont;LOGFONTlf;memset(&lf,0,sizeof(LOGFONT));lf.lfHeight=20;//字体的高font.CreateFontIndirect(&lf);dc.SelectObject(&font);dc.SetTextColor(RGB(255,255,255));dc.SetBkMode(TRANSPARENT);dc.TextOut(DISP_X,DISP_Y-30,L"母亲节");}但是很奇怪,如果是在OnPaint调用feastdate,可以在窗口看到输出文字voidCcalendar::OnPaint(){if(IsIconic()){CPaintDCdc(this);//用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND,reinterpret_cast<WPARAM>(dc.GetSafeHdc()),0);//使图标在工作区矩形中居中intcxIcon=GetSystemMetrics(SM_CXICON);intcyIcon=GetSystemMetrics(SM_CYICON);CRectrect;GetClientRect(&rect);intx=(rect.Width()-cxIcon+1)/2;inty=(rect.Height()-cyIcon+1)/2;//绘制图标dc.DrawIcon(x,y,m_hIcon);}else{CRectrect;CPaintDCdc(this);GetClientRect(rect);CDCdcMem;dcMem.CreateCompatibleDC(&dc);CBitmap*pbmpOld=dcMem.SelectObject(&m_Background);dc.StretchBlt(0,0,534,421,&dcMem,0,0,534,421,SRCCOPY);dc.FillSolidRect(rect,RGB(85,131,216));//设置为绿色背景feastdate(Year,Month,Day,dc);CDialog::OnPaint();}}如果在通过其他函数调用,则看不到输出文字,一直搞不懂,我是初学者,还望大师指教。voidCcalendar::OnBnClickedtoday(){CPaintDCdc(this);//devicecontextforpaintingfeastdate(dc);Invalidate();}
解决方案
解决方案二:
回帖是一种美德!每天回帖即可获得10分可用分!
解决方案三:
最好写在onpaint里
解决方案四:
我想知道原因,为什么会出现这种情况,因为我要通过voidCcalendar::OnBnClickedtoday()刷新,如果放在onpaint只能执行一次了
解决方案五:
怎么没人回答罗
解决方案六:
CPaintDC&dc,这是传过来的参数,你看一下CPaintDC()的原型,没有TextOut()成员函数。把他改为CDC&dc
解决方案七:
TextOut是CPaintDC的成员函数啊,否则在CPaintDC中执行就会有问题了,但为何通过传递就不行了呢?
解决方案八:
个人感觉应该放在onpaint里,因为这里有个重画的问题,如果不放在onpaint里,重画后字体会消逝,如果想多次显示可以调用onpaint
解决方案九:
这是我在网上看到的别人写的代码,是通过voidCcalendar::OnBnClickedtoday(){m_year.SetCurSel(2050-Year);//显示当前年份m_month.SetCurSel(Month-1);//显示当前月份WORDiDay=Day;if(Day>m_oCalendar.MonthDays(Year,Month))iDay=m_oCalendar.MonthDays(Year,Month);m_oCalendar.SetDate(Year,Month,iDay);CPaintDCdc(this);//devicecontextforpaintingm_oCalendar.PaintOneDay(dc);feastdate(Year,Month,iDay,dc);Invalidate();}调用的,为什么这里不通过onpaint调用也能正常显示,这代码我亲自测试过,确实可以的voiddatacomputer::PaintOneDay(CPaintDC&dc){chartext[5];sprintf(text,"%2d",iDay);CStringstr;str=text;if(iDay++==m_iDay)//当天颜色突出{dc.FillRect(&CRect(startx-13,starty-2,startx+40,starty+25),&CBrush(RGB(255,0,0)));dc.SetTextColor(RGB(0,255,0));dc.SetBkMode(TRANSPARENT);dc.TextOut(startx-10,starty+2,str);sprintf(text,"%s",datetext[iLunarDay-1]);str=text;dc.TextOut(startx+5,starty+2,str);dc.SetBkColor(m_dwBackColor);dc.SetTextColor(m_dwForeColor);}else{dc.TextOut(startx-10,starty+2,str);sprintf(text,"%s",datetext[iLunarDay-1]);str=text;dc.TextOut(startx+5,starty+2,str);}}
解决方案十:
你如果要想在窗口的某个区域内输出信息就必须通过窗口重绘才能显示,你上边的语句因为调用了Invalidate();间接调用了onpaint实现了窗口重绘所以才显示了。
解决方案十一:
Invalidate();语句是必须加上去的,否则一执行界面的背景颜色就会被擦掉了,不需要重画,但上面的PaintOneDay和feastdate这两句都是在Invalidate前执行的,按道理应该两个同时出现同样的现象啊,为何一个正常一个不正常呢
解决方案十二:
试着调整下位置(坐标).看看能否输出,考虑下是不是隐射模式的问题.猜的...
解决方案十三:
把Invalidate()去掉刚写上就被擦掉了,当然看不见了
解决方案十四:
把Invalidate()去掉后界面刷新时会把背景颜色擦掉,这时能看到确实有字符显示,但怎么解决这个矛盾呢?
解决方案十五:
我的也是这问题啊,我用的api显示,不能显示时间啊
解决方案:
该回复于2016-03-31 23:47:47被版主删除
解决方案:
同样学习
解决方案:
学习了!
解决方案:
学习。。。
解决方案:
应该把绘图的操作都放到onPaint里去,这是Windows显示原理决定的,因为任何引起窗口重绘的消息(最大最小化窗口,窗口被其他程序窗口遮蔽后又恢复等等)都可以让系统按照onPaint函数的逻辑重绘窗口,这样你所有没有被onPaint认可的绘图操作(即在onPaint外对dc的操作)都会在重绘后丢失(Invalidate()这个函数在后台实现里就激活了onPaint,所以时间显示不出来).因此应该在onPaint里调用feastdate,如果这个feastdate很复杂,可以先在feastdate里面计算好那个str,然后把str放到一个全局属性变量strResult里,最后在onPaint直接显示strResult即可。
解决方案:
Invalidate()函数不会立即重绘窗口,会产生一个WM_PAINT消息到应用程序的消息队列中,如果此时加上UpdateWindow()的话,则会立即重绘窗口,应用程序会调用OnPaint()方法来重绘,如果是CView的子类,则在OnPaint()方法中调用OnDraw()来实现该功能。另外,CPaintDC类只能用于WM_PAINT消息中,如果在其他消息中则需要用CClientDC或者CWindowDC。
解决方案:
学习学习
解决方案:
引用3楼laonong2001的回复:
我想知道原因,为什么会出现这种情况,因为我要通过voidCcalendar::OnBnClickedtoday()刷新,如果放在onpaint只能执行一次了
LZ说在onpaint只能执行一次了是错误的每次调用窗口区域无效果需要重绘时MFC会自动调用onpaint所以放在onpaint里你可以放心了不是只在窗口建立的时候才进行一次绘制的
解决方案:
学习中。。。。
解决方案:
引用3楼laonong2001的回复:
我想知道原因,为什么会出现这种情况,因为我要通过voidCcalendar::OnBnClickedtoday()刷新,如果放在onpaint只能执行一次了
onpaint()在每一次窗口重绘时系统自动调用,OnBnClickedtoday()只有你单击,才会运行每当onpaint()运行时,会把整个窗口重绘一遍,自然就把你的textout输出的字给覆盖掉了,所以要在界面上输出的话就在onpaint()里面,就不会被覆盖掉
解决方案:
hehehao
解决方案:
学习难阿