我在这边是想做一个PHOTOSHOP型的直方图显示
其中,IDC_STATIC_HIST是静态文本区,在它上面画图;m_nHist[256]是直方图数据
主要问题:
1、程序中dc和pDc控制画图上有什么区别,我直接用dc画图竟什么都画不出来;
2、就是用pDc画,其显示效果的坐标位置为什么会和静态文本区有偏离呢
3、?处,为什么要有这两句void CDlgHistogram::OnPaint() 
{
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
CRect histRect;

CWnd* pWnd = GetDlgItem(IDC_STATIC_HIST);
CDC* pDC = pWnd->GetDC();
pWnd->GetWindowRect(&histRect); pWnd->Invalidate();//?
pWnd->UpdateWindow();//?
ScreenToClient(&histRect); UINT maxHeight = histRect.bottom - histRect.top;
CPen *oldPen;
oldPen = (CPen*)pDC->SelectStockObject(BLACK_PEN);//--
for(UINT i=0 ;i<256;i++)
{
UINT biLeft = histRect.left+i+1;
UINT biHeight ;
if((biHeight = m_nHist[i]/100) > maxHeight) biHeight = maxHeight;
pDC->MoveTo(biLeft,histRect.bottom);
pDC->LineTo(biLeft,histRect.bottom - biHeight); }
//--
pDC->SelectObject(oldPen);

// Do not call CDialog::OnPaint() for painting messages
}

解决方案 »

  1.   

    1、程序中dc和pDc控制画图上有什么区别,我直接用dc画图竟什么都画不出来;
    2、就是用pDc画,其显示效果的坐标位置为什么会和静态文本区有偏离呢
    3、?处,为什么要有这两句pDc 只是指针,应该都可以的IDC_STATIC_HIST 可能还有些边缘吧,你拖动把蓝线靠边试试可以不要吧,具体我没试过,你可以试试2楼的方法
      

  2.   

    1.画图有偏差应该是因为你使用了静态文本框的CDC,但坐标却又使用了相对于CDialog的客户坐标
    2.如果使用dc其实已经是画出来了,只是在更新的时候静态文本框也更新结果将所画的图覆盖了,尝试将静态文本框的属性修改成隐藏。之后可能还会又些小问题,闪烁等等
      

  3.   

    rnl(rnl) 讲的很对,我把ScreenToClient(&histRect);改为pWnd->ScreenToClient(&histRect);坐标偏移就解决了
      

  4.   

    而且为什么把CPaintDC dc(this); 删掉就会引起闪烁呢,程序中并没用到这个啊~~
      

  5.   

    转:2.3.2  设备描述表在MFC中的实现
    MFC提供了CDC类作为设备描述表类的基类,它封装了Windows的HDC设备描述表对象和相关函数。
    (1) CDC类
    CDC类包含了各种类型的Windows设备描述表的全部功能,封装了所有的Win32 GDI 函数和设备描述表相关的SDK函数。在MFC下,使用CDC的成员函数来完成所有的窗口绘制工作。
    CDC类的结构示意图2-2所示。
     CDC类有两个成员变量:m_hDC,m_hAttribDC,它们都是Windows设备描述表句柄。CDC的成员函数作输出操作时,使用m_Hdc;要获取设备描述表的属性时,使用m_hAttribDC。
    在创建一个CDC类实例时,缺省的m_hDC等于m_hAttribDC。如果需要的话,程序员可以分别指定它们。例如,MFC框架实现CMetaFileDC类时,就是如此:CMetaFileDC从物理设备上读取设备信息,输出则送到元文件(metafile)上,所以m_hDC和m_hAttribDC是不同的,各司其责。还有一个类似的例子:打印预览的实现,一个代表打印机模拟输出,一个代表屏幕显示。
    CDC封装::SelectObject(HDC hdc,HGDIOBJECT hgdiobject)函数时,采用了重载技术,即它针对不同的GDI对象,提供了名同而参数不同的成员函数:
    SelectObject(CPen *pen)用于选入笔;
    SelectObject(CBitmap* pBitmap)用于选入位图;
    SelectObject(CRgn *pRgn)用于选入剪裁区域;
    SelectObject(CBrush *pBrush)用于选入刷子;
    SelectObject(CFont *pFont)用于选入字体;
    至于调色板,使用SelectPalette(CPalette *pPalette,BOOL bForceBackground )选入调色板到设备描述表,使用RealizePalletter()实现逻辑调色板到物理调色板的映射。
    (2) 从CDC派生出功能更具体的设备描述表
    从CDC 派生出四个功能更具体的设备描述表类。层次如图2-3所示。 下面,分别讨论派生出的四种设备描述表。
    l CCientDC
    代表窗口客户区的设备描述表。其构造函数CClientDC(CWnd *pWin)通过::GetDC获取指定窗口的客户区的设备描述表HDC,并且使用成员函数Attach把它和CClientDC对象捆绑在一起;其析构函数使用成员函数Detach把设备描述表句柄HDC分离出来,并调用::ReleaseDC释放设备描述表HDC。
    l CPaintDC
    仅仅用于响应WM_PAINT消息时绘制窗口,因为它的构造函数调用了::BeginPaint获取设备描述表HDC,并且使用成员函数Attach把它和CPaintDC对象捆绑在一起;析构函数使用成员函数Detach把设备描述表句柄HDC分离出来,并调用::EndPaint释放设备描述表HDC,而::BeginPaint和::EndPaint仅仅在响应WM_PAINT时使用。
    l CMetaFileDC
    用于生成元文件。
    l CWindowDC
    代表整个窗口区(包括非客户区)的设备描述表。其构造函数CWindowDC(CWnd *pWin)通过::GetWindowDC获取指定窗口的客户区的设备描述表HDC,并使用Attach把它和CWindowDC对象捆绑在一起;其析构函数使用Detach把设备描述表HDC分离出来,调用::ReleaseDC释放设备描述表HDC。
      

  6.   

    1. dc是CDlgHistogram的DC
    2. pDC是IDC_STATIC_HIST静态文本控件的DC.
    3. 这种在一个窗口的OnPaint里话另外窗口的做法不好.