我写了一个sdk程序,往窗口增加了一个listbox 控件
现在我想给listbox图片背景设置自己的图片
代码如下:void DrawListBoxBkBitmap(HWND hwndDlg, HDC &hDC)
{
HDC hdcs;
hdcs = ::CreateCompatibleDC(hDC);
HBITMAP m_hBitmap;
BITMAP bm;
m_hBitmap=(HBITMAP)::LoadImage(NULL,"3.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
GetObject(m_hBitmap, sizeof (BITMAP), &bm); SelectObject(hdcs, m_hBitmap); RECT rc;
::GetWindowRect(hwndDlg, &rc);
::SetStretchBltMode(hDC,COLORONCOLOR);
::StretchBlt(hDC, 0, 0, rc.right, rc.bottom, hdcs, 0, 0, bm.bmWidth, bm.bmHeight,+SRCCOPY);
}BOOL CALLBACK ListBoxProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = FALSE;
switch(msg)
{
case WM_ERASEBKGND:
{
HDC hDC = (HDC)(wParam);
DrawListBoxBkBitmap(hwndDlg, hDC);
}
return TRUE;
}
return CallWindowProc(g_OldListBoxProc, hwndDlg, msg, wParam, lParam);
} //main的回调
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
....
case WM_CREATE:
{
GetWindowRect (hWnd, &rect);
hEdit = CreateWindow (TEXT("LISTBOX"), //控件"类名称"
TEXT("Friend"),
WS_CHILD | WS_VISIBLE |LBS_NOTIFY ,
0,
0,
0,
0,
hWnd,
(HMENU)1000, //控件ID
((LPCREATESTRUCT) lParam)->hInstance, //实例句柄
NULL);
g_OldListBoxProc = (WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (long)ListBoxProc);现在问题,我启动程序发现背景并没有设置,但是我后来往listbox 增加了一项之后就把背景加载上去了。
请问我想以启动程序就有背景,怎么实现?
现在我想给listbox图片背景设置自己的图片
代码如下:void DrawListBoxBkBitmap(HWND hwndDlg, HDC &hDC)
{
HDC hdcs;
hdcs = ::CreateCompatibleDC(hDC);
HBITMAP m_hBitmap;
BITMAP bm;
m_hBitmap=(HBITMAP)::LoadImage(NULL,"3.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
GetObject(m_hBitmap, sizeof (BITMAP), &bm); SelectObject(hdcs, m_hBitmap); RECT rc;
::GetWindowRect(hwndDlg, &rc);
::SetStretchBltMode(hDC,COLORONCOLOR);
::StretchBlt(hDC, 0, 0, rc.right, rc.bottom, hdcs, 0, 0, bm.bmWidth, bm.bmHeight,+SRCCOPY);
}BOOL CALLBACK ListBoxProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = FALSE;
switch(msg)
{
case WM_ERASEBKGND:
{
HDC hDC = (HDC)(wParam);
DrawListBoxBkBitmap(hwndDlg, hDC);
}
return TRUE;
}
return CallWindowProc(g_OldListBoxProc, hwndDlg, msg, wParam, lParam);
} //main的回调
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
....
case WM_CREATE:
{
GetWindowRect (hWnd, &rect);
hEdit = CreateWindow (TEXT("LISTBOX"), //控件"类名称"
TEXT("Friend"),
WS_CHILD | WS_VISIBLE |LBS_NOTIFY ,
0,
0,
0,
0,
hWnd,
(HMENU)1000, //控件ID
((LPCREATESTRUCT) lParam)->hInstance, //实例句柄
NULL);
g_OldListBoxProc = (WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (long)ListBoxProc);现在问题,我启动程序发现背景并没有设置,但是我后来往listbox 增加了一项之后就把背景加载上去了。
请问我想以启动程序就有背景,怎么实现?
要是实在不行,你起来就调用一下擦除背景的消息
HDC hdcs;
hdcs = ::CreateCompatibleDC(hDC);
HBITMAP m_hBitmap;
BITMAP bm;
m_hBitmap=(HBITMAP)::LoadImage(...)hdcs没释放,m_hBitmap每次绘制都加载,也没释放,资源严重泄漏。
RECT rc;
::GetWindowRect(hwndDlg, &rc);
::StretchBlt(hDC, 0, 0, rc.right, rc.bottom, hdcs, 0, 0, bm.bmWidth, bm.bmHeight,+SRCCOPY);GetWindowRect之后应该ScreenToClient转换一下,你用StretchBlt,背景会依你程序位置作不同比例拉伸的。
{
GetWindowRect (hWnd, &rect);
// /*
hEdit = CreateWindow (TEXT("LISTBOX"), //控件"类名称"
TEXT("Friend"),
WS_CHILD | WS_VISIBLE |LBS_NOTIFY ,
0,
0,
0,
0,
hWnd,
(HMENU)1000, //控件ID
((LPCREATESTRUCT) lParam)->hInstance, //实例句柄
NULL);
break;
}
case WM_PAINT:
{
// g_OldListBoxProc = (WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (long)ListBoxProc);
HDC hdcs,hDC;
hDC = GetDC (hEdit);
hdcs = ::CreateCompatibleDC(hDC);
HBITMAP m_hBitmap;
BITMAP bm;
m_hBitmap=(HBITMAP)::LoadImage(NULL,"E:\\XMPP\\dms_im_server\\release\\3.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
GetObject(m_hBitmap, sizeof (BITMAP), &bm); SelectObject(hdcs, m_hBitmap); RECT rc;
::GetWindowRect(hEdit, &rc);
::SetStretchBltMode(hDC,COLORONCOLOR);
::StretchBlt(hDC, 0, 0, rc.right, rc.bottom, hdcs, 0, 0, bm.bmWidth, bm.bmHeight,+SRCCOPY);
::DeleteObject(hdcs);
InvalidateRect(hEdit, NULL, TRUE);
break;
}
奇怪。运行的时候有时有背景,有时又没有背景
case WM_CREATE:
{
GetWindowRect (hWnd, &rect);
// /*
hEdit = CreateWindow (TEXT("LISTBOX"), //控件"类名称"
TEXT("Friend"),
WS_CHILD | WS_VISIBLE |LBS_NOTIFY ,
0,
0,
0,
0,
hWnd,
(HMENU)1000, //控件ID
((LPCREATESTRUCT) lParam)->hInstance, //实例句柄
NULL); g_OldListBoxProc = (WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (long)ListBoxProc);
InvalidateRect(hEdit, NULL, TRUE);
break;
}
。。是这样吗?还是没有加载啊
::StretchBlt(hDC, 0, 0, rc.right, rc.bottom, hdcs, 0, 0, bm.bmWidth, bm.bmHeight,+SRCCOPY);
而在CREATE下面你做的就是 把设备DC建立 BMP读入 都一次完成,不要在WM_PAINT下反复加栽了。用到的变量可以做成全局变量。
应该是在listbox的消息里刷新吧,而不是主窗体
不过下述方法是有效的:
定义一个HBRUSH m_brush变量。
子类化LISTBOX,加载m_hBitmap后,m_brush = CreatePatternBrush(m_hBitmap);
然后父窗口响应WM_CTLCOLORLISTBOX消息,直接返回m_brush。
但是图象是平铺效果,想要拉伸,可以根据其大小CreateCompatibleBitmap创建一个内存图象,拉伸绘制至该图象,利用该图象创建画刷。顺便说一句,创建m_brush后图象句柄就可以释放,m_brush要退出时释放。
然后父窗口响应WM_CTLCOLORLISTBOX消息,直接返回m_brush。 这句话什么意思?LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
。
HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL,"E:\\XMPP\\dms_im_server\\release\\3.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
HBRUSH m_brush; switch (message)
{
case WM_CTLCOLORLISTBOX:
{
m_brush = CreatePatternBrush(hBitmap);
//然后再怎么办? m_brush 这个何时用到?
break;
}
。。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
NOTIFYICONDATA nid;
char str[] = "dms server";
DWORD dwRet;
int i, j, k;
HANDLE *hRecvHandle = NULL;
HMENU hmenu, hsubmenu;
char acTmp[MAX_BUFFER_LEN];
_DMSUSER *usetmp;
RECT rect, rc; HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL,"E:\\XMPP\\dms_im_server\\release\\3.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
HBRUSH m_brush; switch (message)
{
case WM_CTLCOLORLISTBOX:
{
GetWindowRect (hEdit, &rc);
m_brush = CreatePatternBrush(hBitmap);
HDC hDC = (HDC)wParam;
HDC tempHDC = ::CreateCompatibleDC(hDC);
HBITMAP oldBit = (HBITMAP)SelectObject(tempHDC, hBitmap);
BitBlt(hDC, 0, 0, rc.right-rc.left + 10, rc.bottom-rc.top + 10, tempHDC, 0, 0, SRCCOPY);
::SelectObject(tempHDC, oldBit);
DeleteObject((HGDIOBJ)hBitmap);
return (LRESULT)m_brush;
}
现在可以了。但是发现内存一直在涨
case WM_CTLCOLORLISTBOX:
return (LRESULT)m_brush;
就行了,m_brush在WM_CREATE里创建好,程序退出时释放