当前位置:编程学习 > C#/ASP.NET >>

TextOut看不到输出字符显示

我现在使用TextOut进行字符输出,发现看不到输出字符显示,找不到原因,下面是我的部分代码:
void Ccalendar::feastdate(CPaintDC &dc)
{
#define DISP_X  15
#define DISP_Y  210
CFont   font;   
LOGFONT   lf;   
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,可以在窗口看到输出文字
void Ccalendar::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
 CRect rect;
         CPaintDC dc(this);
         GetClientRect(rect);
 CDC dcMem; 
 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();


}
}
如果在通过其他函数调用,则看不到输出文字,一直搞不懂,我是初学者,还望易做图指教。
void Ccalendar::OnBnClickedtoday()
{

CPaintDC dc(this); // device context for painting
feastdate(dc);
Invalidate(); 

}
--------------------编程问答-------------------- 回帖是一种美德!每天回帖即可获得 10 分可用分! --------------------编程问答-------------------- 最好写在onpaint里 --------------------编程问答-------------------- 我想知道原因,为什么会出现这种情况,因为我要通过void Ccalendar::OnBnClickedtoday() 
刷新,如果放在onpaint只能执行一次了 --------------------编程问答-------------------- 怎么没人回答罗 --------------------编程问答-------------------- CPaintDC &dc,这是传过来的参数,你看一下CPaintDC()的原型,没有TextOut()成员函数。
把他改为CDC &dc --------------------编程问答-------------------- TextOut是CPaintDC的成员函数啊,否则在CPaintDC中执行就会有问题了,但为何通过传递就不行了呢? --------------------编程问答-------------------- 个人感觉应该放在onpaint里,因为这里有个重画的问题,如果不放在onpaint里,重画后字体会消逝,如果想多次显示可以调用onpaint --------------------编程问答-------------------- 这是我在网上看到的别人写的代码,是通过void Ccalendar::OnBnClickedtoday()
{
m_year.SetCurSel(2050-Year); //显示当前年份
m_month.SetCurSel(Month-1);  //显示当前月份
WORD iDay=Day;
if(Day > m_oCalendar.MonthDays(Year, Month))
iDay = m_oCalendar.MonthDays(Year, Month); 
m_oCalendar.SetDate(Year, Month, iDay); 
CPaintDC dc(this); // device context for painting
m_oCalendar.PaintOneDay(dc);
feastdate(Year,Month,iDay,dc);
Invalidate(); 


}
调用的,为什么这里不通过onpaint调用也能正常显示,这代码我亲自测试过,确实可以的
void datacomputer:: PaintOneDay(CPaintDC &dc)
{
char text[5];
     sprintf(text, "%2d", iDay);
 CString str;
 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显示,不能显示时间啊 --------------------编程问答-------------------- 支持一下。 --------------------编程问答-------------------- 同样学习 --------------------编程问答-------------------- 学习了! --------------------编程问答-------------------- 学习。。。 --------------------编程问答-------------------- 应该把绘图的操作都放到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 的回复:
我想知道原因,为什么会出现这种情况,因为我要通过void Ccalendar::OnBnClickedtoday() 
刷新,如果放在onpaint只能执行一次了


LZ说在onpaint只能执行一次了 是错误的 每次调用窗口区域无效果需要重绘时MFC会自动调用onpaint
 所以放在onpaint里你可以放心了 不是只在窗口建立的时候才进行一次绘制的  --------------------编程问答-------------------- 学习中。。。。 --------------------编程问答--------------------
引用 3 楼 laonong2001 的回复:
我想知道原因,为什么会出现这种情况,因为我要通过void Ccalendar::OnBnClickedtoday() 
刷新,如果放在onpaint只能执行一次了


onpaint()在每一次窗口重绘时系统自动调用,OnBnClickedtoday()只有你单击,才会运行

每当onpaint()运行时,会把整个窗口重绘一遍,自然就把你的textout输出的字给覆盖掉了,

所以要在界面上输出的话就在onpaint()里面,就不会被覆盖掉 --------------------编程问答-------------------- hehe hao --------------------编程问答-------------------- 学习难阿
补充:.NET技术 ,  VC.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,