请教高手,图形对话框的问题

ququshb 2002-10-18 02:54:53
我做了一个图象的界面,对话框的,在OnPaint中 画上背景图案,然后用Invalidate 方法刷新每个控件,但是控件并没有完全显示出来,特别是CCtrlList 等控件,滚动条有时候显示不出来,CEdit控件边上的3d效果也出不来,这是怎么了?哪位大虾指点指点!
...全文
85 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
蒋晟 2002-10-22
  • 打赏
  • 举报
回复
Platform SDK: Windows User Interface
WM_ERASEBKGND
The WM_ERASEBKGND message is sent when the window background must be erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting.

A window receives this message through its WindowProc function.

LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // WM_ERASEBKGND
WPARAM wParam, // handle to device context (HDC)
LPARAM lParam // not used
);
Parameters
wParam
Handle to the device context.
lParam
This parameter is not used.
Return Values
An application should return nonzero if it erases the background; otherwise, it should return zero.

Remarks
The DefWindowProc function erases the background by using the class background brush specified by the hbrBackground member of the WNDCLASS structure. If hbrBackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.

An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required. If the application returns zero, the window will remain marked for erasing. (Typically, this indicates that the fErase member of the PAINTSTRUCT structure will be TRUE.)

蒋晟 2002-10-22
  • 打赏
  • 举报
回复
Platform SDK: Windows User Interface
WM_ERASEBKGND
The WM_ERASEBKGND message is sent when the window background must be erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting.

A window receives this message through its WindowProc function.

LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // WM_ERASEBKGND
WPARAM wParam, // handle to device context (HDC)
LPARAM lParam // not used
);
Parameters
wParam
Handle to the device context.
lParam
This parameter is not used.
Return Values
An application should return nonzero if it erases the background; otherwise, it should return zero.

Remarks
The DefWindowProc function erases the background by using the class background brush specified by the hbrBackground member of the WNDCLASS structure. If hbrBackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.

An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required. If the application returns zero, the window will remain marked for erasing. (Typically, this indicates that the fErase member of the PAINTSTRUCT structure will be TRUE.)

蒋晟 2002-10-22
  • 打赏
  • 举报
回复
cann HandleOnEraseBackground when handling WM_ERASEBKGND
cann HandleOnDestroywhen handling WM_DESTROY
蒋晟 2002-10-22
  • 打赏
  • 举报
回复
CBackgroundManager::CBackgroundManager()
{
m_hBkgrBitmap = NULL;
m_sizeBkgrBitmap = CSize (0, 0);
m_BkgrLocation = (BackgroundLocation) -1;
m_bAutoDestroyBmp = FALSE;
m_pWnd=NULL;
}

CBackgroundManager::~CBackgroundManager()
{

}
//*************************************************************************************
void CBackgroundManager::SetBackgroundColor (COLORREF color, BOOL bRepaint)
{
if (m_brBkgr.GetSafeHandle () != NULL)
{
m_brBkgr.DeleteObject ();
}

if (color != (COLORREF)-1)
{
m_brBkgr.CreateSolidBrush (color);
}

if (bRepaint && m_pWnd->GetSafeHwnd () != NULL)
{
m_pWnd->Invalidate ();
m_pWnd->UpdateWindow ();
}
}
//*************************************************************************************
void CBackgroundManager::SetBackgroundImage (HBITMAP hBitmap,
BackgroundLocation location,
BOOL bAutoDestroy,
BOOL bRepaint)
{
if (m_bAutoDestroyBmp && m_hBkgrBitmap != NULL)
{
::DeleteObject (m_hBkgrBitmap);
}

m_hBkgrBitmap = hBitmap;
m_BkgrLocation = location;
m_bAutoDestroyBmp = bAutoDestroy;

if (hBitmap != NULL)
{
BITMAP bmp;
::GetObject (hBitmap, sizeof (BITMAP), (LPVOID) &bmp);

m_sizeBkgrBitmap = CSize (bmp.bmWidth, bmp.bmHeight);
}
else
{
m_sizeBkgrBitmap = CSize (0, 0);
}

if (bRepaint && m_pWnd->GetSafeHwnd () != NULL)
{
m_pWnd->Invalidate ();
m_pWnd->UpdateWindow ();
}
}
//*************************************************************************************
BOOL CBackgroundManager::SetBackgroundImage (UINT uiBmpResId,
BackgroundLocation location,
BOOL bRepaint)
{
HBITMAP hBitmap = NULL;

if (uiBmpResId != 0)
{
hBitmap = ::LoadBitmap (AfxGetResourceHandle (),
MAKEINTRESOURCE (uiBmpResId));
if (hBitmap == NULL)
{
ASSERT (FALSE);
return FALSE;
}
}

SetBackgroundImage (hBitmap, location, TRUE /* Autodestroy */, bRepaint);
return TRUE;
}
//virtual
BOOL CBackgroundManager::HandleOnEraseBackground(CDC* pDC)
{
if (m_brBkgr.GetSafeHandle () == NULL && m_hBkgrBitmap == NULL)
{
return FALSE;
}

ASSERT_VALID (pDC);

CRect rectClient;
m_pWnd->GetClientRect (rectClient);

if (m_BkgrLocation != BACKGR_TILE || m_hBkgrBitmap == NULL)
{
if (m_brBkgr.GetSafeHandle () != NULL)
{
pDC->FillRect (rectClient, &m_brBkgr);
}
else
{
return FALSE;
}
}

if (m_hBkgrBitmap == NULL)
{
return TRUE;
}

ASSERT (m_sizeBkgrBitmap != CSize (0, 0));

if (m_BkgrLocation != BACKGR_TILE)
{
CPoint ptImage = rectClient.TopLeft ();

switch (m_BkgrLocation)
{
case BACKGR_TOPLEFT:
break;

case BACKGR_TOPRIGHT:
ptImage.x = rectClient.right - m_sizeBkgrBitmap.cx;
break;

case BACKGR_BOTTOMLEFT:
ptImage.y = rectClient.bottom - m_sizeBkgrBitmap.cy;
break;

case BACKGR_BOTTOMRIGHT:
ptImage.x = rectClient.right - m_sizeBkgrBitmap.cx;
ptImage.y = rectClient.bottom - m_sizeBkgrBitmap.cy;
break;
}

pDC->DrawState (ptImage, m_sizeBkgrBitmap, m_hBkgrBitmap, DSS_NORMAL);
}
else
{
// Tile background image:
for (int x = rectClient.left; x < rectClient.Width (); x += m_sizeBkgrBitmap.cx)
{
for (int y = rectClient.top; y < rectClient.Height (); y += m_sizeBkgrBitmap.cy)
{
pDC->DrawState (CPoint (x, y), m_sizeBkgrBitmap, m_hBkgrBitmap, DSS_NORMAL);
}
}
}

return TRUE;
}
void CBackgroundManager::HandleOnDestroy()
{
if (m_bAutoDestroyBmp && m_hBkgrBitmap != NULL)
{
::DeleteObject (m_hBkgrBitmap);
m_hBkgrBitmap = NULL;
}
}
蒋晟 2002-10-22
  • 打赏
  • 举报
回复
class AFX_EXT_CLASS CBackgroundManager
{
public:
CBackgroundManager();
virtual ~CBackgroundManager();

enum BackgroundLocation
{
BACKGR_TILE,
BACKGR_TOPLEFT,
BACKGR_TOPRIGHT,
BACKGR_BOTTOMLEFT,
BACKGR_BOTTOMRIGHT,
};
protected:
HBITMAP m_hBkgrBitmap;
CSize m_sizeBkgrBitmap;
CBrush m_brBkgr;
BackgroundLocation m_BkgrLocation;
BOOL m_bAutoDestroyBmp;
CWnd* m_pWnd;
public:
void Init(CWnd* pWnd){m_pWnd=pWnd;}
void SetBackgroundColor (COLORREF color, BOOL bRepaint = TRUE);
void SetBackgroundImage (HBITMAP hBitmap,
BackgroundLocation location = BACKGR_TILE,
BOOL bAutoDestroy = TRUE,
BOOL bRepaint = TRUE);
BOOL SetBackgroundImage (UINT uiBmpResId,
BackgroundLocation location = BACKGR_TILE,
BOOL bRepaint = TRUE);
BOOL HandleOnEraseBackground(CDC* pDC);
void HandleOnDestroy();
};
ququshb 2002-10-22
  • 打赏
  • 举报
回复
2 jiangsheng(蒋晟.Net)
怎么我在WindowProc 里判断 WM_ERASEBKGND后,
刷新图片还是不行啊?

LRESULT CSdfadfDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
if (message == WM_ERASEBKGND )
{
TRACE("WM_ERASEBKGND.\n");

ASSERT(m_pFace != NULL);
LPBITMAPINFOHEADER pInHeader = (LPBITMAPINFOHEADER)m_pFace;
char *pBuf = m_pFace + sizeof(BITMAPINFOHEADER);
HDC hDc;
hDc = GetDC ()->GetSafeHdc ();

DrawDibDraw(hdib,
hDc,
0,0,
pInHeader->biWidth ,
pInHeader->biHeight ,
pInHeader,
pBuf,
0,0,
pInHeader->biWidth ,
pInHeader->biHeight ,
DDF_BACKGROUNDPAL);
::ReleaseDC (this->m_hWnd,hDc);
m_l1.Invalidate ();
m_l2.Invalidate ();
m_l3.Invalidate ();
m_l4.Invalidate ();
return 1;
}

return CDialog::WindowProc(message, wParam, lParam);
}

能留下e-mail 吗 发给大家帮我看看
ququshb 2002-10-22
  • 打赏
  • 举报
回复
又弄了一下
发现当背景图很大的时候,这个现象很明显
lhb_780902 2002-10-21
  • 打赏
  • 举报
回复
Layout->Tab order 将图像控件的order值设为1
ququshb 2002-10-21
  • 打赏
  • 举报
回复
2 everandforever(Forever) ( )
你的那个做法,好象不管用哦
CharmDream 2002-10-21
  • 打赏
  • 举报
回复
gz
ququshb 2002-10-21
  • 打赏
  • 举报
回复
请问 jiangsheng(蒋晟.Net):
对话框的 classwizrd 中没有 onEraseBackground啊,你的意思是直接填加 onEraseBackground ()吗?
顺便问问,我的三角形怎么成立 2个了,少了2个了
ququshb 2002-10-21
  • 打赏
  • 举报
回复
2 : kwiner(最爱编程)
你把控件的 Ower draw 设置上就可以了
cooljjyy 2002-10-19
  • 打赏
  • 举报
回复
何必要用图像控件呢?
kwiner 2002-10-18
  • 打赏
  • 举报
回复
我是用图像控件来放背景的

用你的方法我没有成功
蒋晟 2002-10-18
  • 打赏
  • 举报
回复
在onEraseBackground里面用图片擦除背景
wxdnuaa 2002-10-18
  • 打赏
  • 举报
回复
加一个函数呢?
// Invalidate window so entire client area
// is redrawn when UpdateWindow is called.
Invalidate();
UpdateWindow();
everandforever 2002-10-18
  • 打赏
  • 举报
回复
ONPAINT()
{
.........

CCtrlList->RedrawWindow();//用REDRAWWINDOW代替Invalidate
滚动条->RedrawWindow();
CEdit->RedrawWindow();
}

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧