Sign in to follow this  
TTK-Bandit

Win32 Background on Edit Control

Recommended Posts

Hey I'm trying to draw a background on an edit control. I've got it working til the point when the edit gets scrolled from the user. Then it will only draw on top of the previously drawn, so a blur gets drawn. When scrolled completely to the bottom however, it refreshes the complete view. My current approach does this: in the mainwindows windowproc:
		case WM_CTLCOLORSTATIC:
			if ( ( HWND ) lParam == hWndEdit ) {
				SetBkMode( ( HDC ) wParam, TRANSPARENT );
				return 0;
			}
			break;
and in the edit windows proc, I check for WM_ERASEBKGND and draw the bitmap and return 1. I guess I need to find a message that gets send to my edit control whenever it changed the scroll position. But EM_SCROLL does not get send, and WM_VSCROLL only happens when I use the mouse to move the scrollbar. I tried calling SendMessage( hWnd, WM_ERASEBKGND, (WPARAM)GetDC(hWnd), 0 ) on the WM_VSCROLL event, but that was really flickering. I tried working with WS_EX_TRANSPARENT and adding a static image behind the edit control, but for some reason, the transparent doesn't do what I thought it would. Any ideas how to make it work nicely ? All I want is a fixed size image drawn in the center of the edit control.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rattrap
WM_CTLCOLORSTATIC should be returning a brush, not 0.

Quote:

If an application processes this message, the return value is a handle to a brush that the system uses to paint the background of the static control.

But the OP wants to have control over the background painting, no?

Also, IIRC this brush is only used for the background of the area where text can actually lie, not the entirety of the edit control.

As an aside: OP, why aren't you using WM_CTLCOLOREDIT?

Share this post


Link to post
Share on other sites

if ( uMsg == WM_ERASEBKGND ) {
// Setup Drawing
HDC hdc = (HDC)wParam;
HDC hcompdc = CreateCompatibleDC(hdc);

// Get area to draw
RECT destRect;
GetClientRect(hWnd, &destRect);

// Fill the background
FillRect( hdc, &destRect, hbrEditBg );

// find the center rect
destRect.left += (destRect.right - destRect.left)/2 - wcd.bgImgWidth/2;
destRect.top += (destRect.bottom - destRect.top)/2 - wcd.bgImgHeight/2;
RECT srcRect = { 0, 0, bgImgWidth, bgImgHeight };

// Adjust source and destination rect, if out of bounds
if ( destRect.top < 0 ) {
srcRect.top = -destRect.top;
srcRect.bottom -= -2*destRect.top;
destRect.top = 0;
}
if ( destRect.left < 0 ) {
srcRect.left = -destRect.left;
srcRect.right -= -2*destRect.left;
destRect.left = 0;
}

// Draw the image
SelectObject(hcompdc, hBackBmp);
StretchBlt(hdc, destRect.left, destRect.top, srcRect.right, srcRect.bottom,
hcompdc, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom, SRCCOPY);

DeleteDC(hcompdc);
return 1;
}


Rattrap: doesn't matter, it does the same as creating a HOLLOW_BRUSH

Share this post


Link to post
Share on other sites
I knew of an old Article on how to display an Image on the Background of a Richedit Control. I think it was on codeproject.
It is not an easy Task. There is a lot of incremental painting in both Edit and Richedit controls. The best long term Solution is to create your own custom Control.

Share this post


Link to post
Share on other sites
got it working using richedit:
::LoadLibrary(L"Riched20.dll");
hWndEdit = CreateWindowEx(WS_EX_TRANSPARENT, L"RICHEDIT20W", L"",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL,
0, 0, 0, 0, hWndMain, MY_EDIT_ID, hInstance, NULL );


then subclass the window and do:

if ( uMsg == WM_ERASEBKGND ) {
// Setup Drawing
HDC hdc = (HDC)wParam;
HDC hcompdc = CreateCompatibleDC(hdc);

// Get area to draw
RECT destRect, wndRect;
GetClientRect(hWndEdit, &wndRect);
GetClientRect(hWndEdit, &destRect);

// find the center rect
destRect.left += (destRect.right - destRect.left)/2 - bgImgWidth/2;
destRect.top += (destRect.bottom - destRect.top)/2 - bgImgHeight/2;
RECT srcRect = { 0, 0, bgImgWidth, bgImgHeight };

// Adjust source and destination rect, if out of bounds
if ( destRect.top < 0 ) {
srcRect.top = -destRect.top;
srcRect.bottom -= -2*destRect.top;
destRect.top = 0;
}
if ( destRect.left < 0 ) {
srcRect.left = -destRect.left;
srcRect.right -= -2*destRect.left;
destRect.left = 0;
} else {
RECT tRect = { 0, 0, destRect.left, wndRect.bottom };
FillRect( hdc, &tRect, hbrEditBg );
}
destRect.right = destRect.left + srcRect.right;
destRect.bottom = destRect.top + srcRect.bottom;
if ( destRect.right < wndRect.right ) {
RECT tRect = { destRect.right, 0, wndRect.right, wndRect.bottom };
FillRect( hdc, &tRect, hbrEditBg );
}
if ( destRect.left > 0 ) {
RECT tRect = { destRect.left, 0, destRect.right, destRect.top };
FillRect( hdc, &tRect, hbrEditBg );
}
if ( destRect.bottom < wndRect.bottom ) {
RECT tRect = { destRect.left, destRect.bottom, destRect.right, wndRect.bottom };
FillRect( hdc, &tRect, hbrEditBg );
}

// Draw the image
SelectObject(hcompdc, hBackBmp);
BitBlt(hdc, destRect.left, destRect.top, srcRect.right, srcRect.bottom, hcompdc, srcRect.left, srcRect.top, SRCCOPY);

DeleteDC(hcompdc);
return 1;
}

One might wonder why I call fillrect 4 times instead of once for the whole background, that is to avoid flickering.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this