WM_PAINT msgs are generated when the client area of an app needs to be re-drawn.
Paint msgs can be generated by your app or by external events (ie another window passing over your app).
You generate a WM_PAINT inside your app by calling;
InvalidateRect() which generates the paint msg to the required callback.
UpdateWindow() usually follows InvalidateRect() as it sends the paint msg directly to the callback (instead of the paint msg going to the OS msg queue). This makes the painting faster and smoother.
Controls do not generate paint msgs.
The OS handles redrawing controls and the coder has no control over the drawing, unless you specify OWNERDRAW and handle the WM_DRAWITEM msg.
It is all done in the WM_DRAWITEM handler.
If you need to redraw the control after some user input / event / etc then you can use SendMessage() to generate a WM_DRAWITEM msg (just as you use InvalidateRect() + UpdateWindow() to generate a WM_PAINT).
In your case you need to do something like this;
[note written from memory, not compiled or any error handling added and so should not be used...]
Code:
//made static to retain value between msgs
static HBITMAP hImage = null;
static HDC hdcMem = null, hbmpOld = null;
case WM_INITDIALOG: //or WM_CREATE depending on if a window or a dialog
{
//load the bitmap (do it here to save time while drawing)
hImage =(HBITMAP)LoadImage(NULL,FileName.c_str(),IMAGE_BITMAP,20,20,LR_LOADFROMFILE);
//create memory DC to hold image
HDC hdc = GetDC(GetDlgItem(hWnd, ID_OWNER_DRAWN_STATIC)); //get controls DC
hdcMem = CreateCompatibleDC(hdc); //create a DC the same as it
hbmpOld = (HBITMAP) SelectObject(hdcMem, hImage); //select the image into the memory DC
//if the text on the image does not change during run time, draw it here
//clean up
ReleaseDC(hdc);
return TRUE;
}
case WM_DESTROY: //when the app closes
{
//clean up image
//put the memory DC back to default
SelectObject(hdcMem, hbmpOld);
//and delete the GDIs we created
DeleteDC(hdcMem);
DeleteObject(hImage);
return TRUE;
}
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT pDrawItem = (LPDRAWITEMSTRUCT)lParam;
//check it is the static we want to draw
if (pDrawItem >hwndItem == GetDlgItem(hWnd, ID_OWNER_DRAWN_STATIC) )
{
//draw the image, assumes image and control are the same size
BitBlt(pDrawItem->hDC,
pDrawItem->rcItem.left, pDrawItem->rcItem.top,
pDrawItem->rcItem.right - pDrawItem->rcItem.left,
pDrawItem->rcItem.bottom - pDrawItem->rcItem.top,
hdcMem, 0, 0, SRCCOPY);
//get the text to draw on the image (assume it is in 'TextToDraw' string variable)
//draw text
//NOTE we draw to the controls DC (not the memory DC) so we can change the text as required
//and not have remnants of the last text showing
//if the text does not change then it should be draw on the memory DC in the WM_CREATE (move the lines)
TextOut(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, TextToDraw.c_str(), TextToDraw.Length() );
//we did not create any GDIs so no cleanup required
//tell OS we processed this msg
return TRUE;
}
return FALSE; //we did not process this msg
}