0
votes

Im using the default Windows.h functions to draw. I use StretchBlt to draw a bitmap. but it(StretchBlt) draws a blank bitmap (i.e its total blackness if I dont use WHITENESS in rop).

I have a struct to draw the components

The section of the VM_PAINT

PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
SetStretchBltMode(hdc, WHITEONBLACK);
cv.DrawComponents(hdc);
EndPaint(hwnd, &ps);

on DrawComponents():

HDC hdcMem = CreateCompatibleDC(hdc);
            for (int i = 0; i < size; i++)
            {
                if (spaceFlags[i]) components[i]->Draw(hdc, hdcMem, Screen_Multiplier);
            }
            DeleteDC(hdcMem);

Finally the components:

class ElectriComp
    {
    protected:
        unsigned short connectionNum;
        float x = 0, y = 0, cx = 0.5, cy = 0.5; 
        COORD dimentions;
        PBITMAP bitmap;

    public:
        
        unsigned int* Connections;
        ElectriComp(unsigned short connectionnum, PBITMAP b) 
            : connectionNum{ connectionnum }
        {
            bitmap = b;
            Connections = new unsigned int[connectionNum];
        }

        void SetPlace(int x, int y)
        {
            this->x = x;
            this->y = y;
        }

        void Draw(HDC hdc, HDC hdcMem, float ScreenMul)
        {
            HGDIOBJ old = SelectObject(hdcMem, CreateBitmapIndirect(bitmap));
            StretchBlt(hdc, (x - cx) * ScreenMul, (y - cy) * ScreenMul, dimentions.X * ScreenMul, dimentions.Y * ScreenMul, hdcMem, 0, 0, bitmap->bmWidth, bitmap->bmHeight, SRCCOPY);
            SelectObject(hdcMem, old);
        }
        ~ElectriComp()
        {
            delete Connections;
        }
    };

Edit#1: As was pointed out, I passed PBITMAP instead HBITMAP. I got Handle through the CreateBitmapIndirect. The problem still persists, the image on screen is still blank while SelectObject doesnt return NULL.

Edit#2: changed the drawing rotine to:

void DrawComponents(HDC hdc)
        {
            HDC hdcMem = CreateCompatibleDC(hdc);
            COLORREF prevC = SetTextColor(hdc, RGB(255, 0, 0));
            COLORREF prevB = SetBkColor(hdc, RGB(0, 255, 0));
            for (int i = 0; i < size; i++)
            {
                if (spaceFlags[i])
                {
                    components[i]->Draw(hdc, hdcMem, Screen_Multiplier, benchSpace.left, benchSpace.top);
                }
            }
            DeleteDC(hdcMem);
        }

I get a Red square. So I think the problem is in the loadbitmap. here is the rotine for it:

case WM_CREATE:
        GetObject(LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(ResistorBMP)), sizeof(resistorBM), &resistorBM);
        return 0;

ResistorBMP is a bitmap in my resources.

1
You haven't shown enough code. How is your bitmap created?Jonathan Potter
@JonathanPotter I load it from resources. Its an 1bit 25x25 bitmap.Warmagedon 007
You may need to set the text/background colors when blitting a monochrome bitmap. See devblogs.microsoft.com/oldnewthing/20061114-01/?p=29013.Jonathan Potter
PBITMAP and HBITMAP are not the same thing at all. SelectObject wants the latter, but you are passing the former. Check the return value of SelectObject; I predict it fails.Igor Tandetnik

1 Answers

1
votes

As @IgorTandetnik pointed out, SelectObject expects HBITMAP instead of PBITMAP.

Additionally, make sure the bitmap is a valid bitmap. For example, if you load the bitmap using LoadImage, make sure the return value is a valid handle instead of NULL.

The following is working example you can refer to:

        HBITMAP HBitmap = (HBITMAP)LoadImage(NULL, L"test.bmp", IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);

        BITMAP bitmap;
        int iReturn = GetObject(HBitmap, sizeof(BITMAP), (LPSTR)(&bitmap));

        RECT client;
        GetClientRect(hWnd, &client);

        HGDIOBJ old = SelectObject(hdcMem, HBitmap);
        StretchBlt(hdc, 0, 0, client.right, client.bottom, hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);

At last, add error checking for function calls will help you find the problem.