I am setting the font for a control like this:
HDC hdc = GetDC(NULL);
int lfHeight = -MulDiv(szFont, GetDeviceCaps(hdc, LOGPIXELSY), 72);
ReleaseDC(NULL, hdc);
HFONT font = CreateFont(lfHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Font.c_str());
SendMessage(hwnd,WM_SETFONT,(WPARAM)font,0);
The control is a static. How would I find the width of the text in the static for a given string?
Use GetTextExtentPoint32. You'll need to select the font into the DC first.
CDC::GetTextExtent() and CDC::GetOutputTextExtent() should help.
Related
From this post,
Let's say I want to calculate the textwidth in point of "Meet".
I use the following code:
HFONT hFont, hOldFont;
double fontheight = 12; <--font height in point
HDC hDC = GetDC(0);
// get a 12-point font and select it into the DC
int currentY = MulDiv((int)fontheight, GetDeviceCaps(hDC, LOGPIXELSY), 72);
hFont = CreateFont(-currentY, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0,
0, 0, 0, 0, L"Arial"));
hOldFont = SelectFont(hDC, hFont);
TEXTMETRIC textMetric;
GetTextMetrics(hDC, &textMetric); <--this function return char height=18/charwidth=7
double fontwidth = fontheight/textMetric.tmHeight* textMetric.tmAveCharWidth; //rescale font width base on font height
CString t = L"Meet";
fontwidth =(double) (fontwidth* t.GetLength()); <-fontwidth*4.
Where am I going wrong, because based on the actual image it is quite small?
I have a problem with LoadImage.(Invalid Handle Error*)
HDC screen = CreateCompatibleDC(0);
HDC imageDC = CreateDC(0, 0, 0, 0);
HBITMAP filebmp = (HBITMAP)LoadImage(NULL,_T("C:\\file.bmp"),IMAGE_BITMAP,200,200, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
SelectObject(imageDC, filebmp);
BOOL d = BitBlt(screen, 0, 0, 1920, 1080, imageDC, 0, 0, SRCCOPY);
This is my main Code. Where am I doing wrong?
I searched about it but couldn't find any solution for this.
Problem you may have is that your bitmap file is invalid, you can't just change .jpg to .bmp, your image needs to be saved as bmp.
I'm a little confused on how to double buffer this. I'm
not sure if I need to create another CreateCompatibleBitmap or CreateCompatibleDC and how to link it all.
This works as is but I don't think its double buffered right.
void __OnPaint(HWND hWnd, HDC _hdc = nullptr)
{
HDC hdc = _hdc;
PAINTSTRUCT paint;
RECT& rcClient = paint.rcPaint;
if (!_hdc)
hdc = BeginPaint(hWnd, &paint);
else
GetClientRect(hWnd, &rcClient);
if (hdc)
{
int width = rcClient.right - rcClient.left;
int height = rcClient.bottom - rcClient.top;
HDC hDCMem = CreateCompatibleDC(_hdc);
HBITMAP hBitmapMem = CreateCompatibleBitmap(hDCMem, width, height);
SelectObject(hDCMem, hBitmapMem);
Rectangle(hDCMem, 0, 0, width, height);
BLENDFUNCTION bfn;
bfn.BlendOp = AC_SRC_OVER;
bfn.BlendFlags = 0;
bfn.AlphaFormat = 0;
bfn.SourceConstantAlpha = 0x50;
AlphaBlend(hdc, 0, 0, width, height, hDCMem, 0, 0, width, height, bfn);
SetTextColor(hdc, RGB(255, 0, 0));
SetBkMode(hdc, TRANSPARENT);
DrawText(hdc, "Your text here", -1, &rcClient, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
//BitBlt(hdc, 0, 0, width, height, hDCMem, 0, 0, SRCCOPY);
DeleteDC(hDCMem);
DeleteObject(hBitmapMem);
}
if (!_hdc)
EndPaint(hWnd, &paint);
}
Also i found i have another problem with this.
i move my window in WM_TIMER, i call my __onpaint, problem im having is that it does not redraw it has something todo with the alphaBlend, it keeps what ever was under the window at the time of 1st draw, since it worked before i was using that
double buffering is to do all your printing and drawing on a temporary bitmap, that should be stored somewhere. the drawings on that bitmap can happen outside of WM_PAINT event (eg: on Adding items or selection change).
then on WM_PAINT event, the only thing you have to do is to project that bitmap to the window via BitBlt function or similar functions.
the way you are using AlphaBlend is wrong. AlphaBlend is used to draw images that have an AlphaChanel over an existing image as an overlay.
UPDATED LOOK AT BOTTOM OF THIS POST
What I am doing is trying to use one Black and White bitmap, to lay a background bitmap on the white, and the tile overlay on the black. The problem I am having is adding the overlay.
and this is my BitBlt() code, this code produces #5.
hOldBitmap = (HBITMAP)SelectObject(hdcMem, bitmap.hbmBackground); // #2
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem, 0, 0, SRCCOPY);
hOldBitmap = (HBITMAP)SelectObject(hdcMem, bitmap.hbmMap); // #1
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem, 0, 0, SRCAND);
hOldBitmap = (HBITMAP)SelectObject(hdcMem, bitmap.hbmMapOverlay); // #4
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem, 0, 0, SRCAND);
I am unsure about using the same "hOldBitmp", but it seems to do the same thing either way.
The transparent blt function would not fully suffice here, either.
Thanks.
NEW
I have been having trouble combining and rastoring. I can somewhat handle DC's and bitmaps, but this is one thing I cant figure out how to do... Creating memory dcs, and dcs to hold a bitmap, dc for another bitmap, then bitblt to the mem. I think...
Heres my redundant code I have at the moment. Really I am needing help with pseudo code, how to combine the bitmaps... how many DC's are necessary, etc..
buffer.getBufferDC() is the main DC that displays on the screen.
HDC hdc = GetDC(hWnd);
HDC hdcMem = CreateCompatibleDC(hdc);
HDC hdcMem2 = CreateCompatibleDC(hdc);
HDC hdcMem3 = CreateCompatibleDC(hdc);
HDC hdcMem4 = CreateCompatibleDC(hdc);
HBITMAP hbmMem3 = CreateCompatibleBitmap(hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
HBITMAP hbmMem4 = CreateCompatibleBitmap(hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
ReleaseDC(hWnd, hdc);
// Copy the map and clean the hdcMem
HBITMAP hbmOld;
hbmOld = (HBITMAP)SelectObject(hdcMem, bitmap.hbmMap);
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
hbmOld = (HBITMAP)SelectObject(hdcMem2, bitmap.hbmBackground);
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem2, 0, 0, SRCAND);
SelectObject(hdcMem2, hbmOld);
hbmOld = (HBITMAP)SelectObject(hdcMem3, bitmap.hbmMapOverlay);
hbmOld = (HBITMAP)SelectObject(hdcMem4, bitmap.hbmMap);
BitBlt(hdcMem3, 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem4, 0, 0, SRCINVERT);
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem3, 0, 0, SRCPAINT);
//hbmOld = (HBITMAP)SelectObject(hdcMem, bitmap.hbmMap);
//BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem, 0, 0, SRCPAINT);
//SelectObject(hdcMem, hbmOld);
//hbmOld = (HBITMAP)SelectObject(hdcMem, bitmap.hbmMapOverlay);
//BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem, 0, 0, SRCAND);
//SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
DeleteDC(hdcMem2);
DeleteDC(hdcMem3);
DeleteDC(hdcMem4);
Combine hbmpBackground with hbmMap using SRCAND, as you've done in 3.
Combine hbmMapOverlay with an inverted hbmMap (SRCINVERT should do it).
Combine those two results using OR (SRCPAINT)
Although this can be done with BitBlt, it's usually quite a bit easier to use PlgBlt.
Start by BitBlting the background bitmap to the destination. Then call PlgBlt, passing it both the foreground bitmap and the mask.
I would like to owner-draw a red border to a EDIT or Push button in C++ win32 api. NO MFC Please.
I have gotten this far. Drawing a black border but most if not all the hButtonDC,hButtonBitmap are undeclared.
PAINTSTRUCT ps;
HDC hdc;
HBRUSH hBrush;
BeginPaint(hwndButton2, &ps);
// Create memory DC to contain hButtonBitmap
hButtonDC = CreateCompatibleDC(ps.hdc);
hButtonBitmap = SelectObject(hButtonDC, hButtonBitmap);
// Create second memory DC where the button borders will be drawn and select into this DC an empty bitmap with the
// size of the button bitmap
hMemDC = CreateCompatibleDC(ps.hdc);
hBitmap = CreateCompatibleBitmap(ps.hdc, ps.rcPaint.right, ps.rcPaint.bottom);
hBitmap = SelectObject(hMemDC, hBitmap);
// Copy hButtonDC into hMemDC
BitBlt(hMemDC, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom, hButtonDC, 0, 0, SRCCOPY);
// Paint the button borders with black pixels (1 pixel width)
PatBlt(hMemDC, 0, 0, ps.rcPaint.right - 1, 1, BLACKNESS);
PatBlt(hMemDC, ps.rcPaint.right - 1, 0, 1, ps.rcPaint.bottom, BLACKNESS);
PatBlt(hMemDC, 0, ps.rcPaint.bottom - 1, ps.rcPaint.right , 1, BLACKNESS);
PatBlt(hMemDC, 0, 0, 1, ps.rcPaint.bottom - 1, BLACKNESS);
// Paint the button with drawn borders to its window DC, ps.hdc .
BitBlt(ps.hdc, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom, hMemDC, 0, 0, SRCCOPY);
// Delete hBitmap e hMemDC
DeleteObject(SelectObject(hMemDC, hBitmap));
DeleteDC(hMemDC);
// Delete hButtonDC
SelectObject(hButtonDC, hButtonBitmap);
DeleteDC(hButtonDC);
EndPaint(hWnd, &ps);