0

Im new in MFC/C++ an Im trying to fill my windows with pixels.I found out that there is a function which is called :

SetPixel(X,Y,RGB(,,));

After I tried to put use it in my loop I found out that this function stops after an amount of pixels.So It don't give me the result I actually want to reach. Here is my code :

void PIXELPROG::OnPaint() { if (IsIconic()) { CPaintDC dc(this); SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } CStatic * XText = (CStatic *)GetDlgItem(IDC_X); CStatic * YText = (CStatic *)GetDlgItem(IDC_YWERT); CString XYWert; for (int x=0,y=0;;) { GetDC()->SetPixelV(x, y, RGB(y,x,y)); XYWert.Format(L"%d",y); XText->SetWindowTextW(XYWert); ++x; if (x == 500) { ++y; x = 0; } if (y == 100) { break; } } } 

I also don't get any errors.It is just stopping. I also tried it with

SetPixelV()

But didn't helped neither. Someone got an idea ?

4
  • How big is the windows client-area? What if the coordinates don't go as high as you think? What if you're overwriting the graphics memory of another widget? Commented Mar 5, 2015 at 17:48
  • Actually there is enough place there.And how can I check it up ? I thought I have to put this code in the onPaint function. Commented Mar 5, 2015 at 17:51
  • You can check the client area dimensions with GetClientRect. Commented Mar 5, 2015 at 18:15
  • Just a guess without checking the sources: SetWindowTextW() uses the message queue which overflows, blocking further messages. Since you are inside a message handler, the messages can't be handled. What are you trying to do with that loop? Maybe a different approach to solving your real problem would help. Commented Mar 5, 2015 at 18:25

2 Answers 2

2

From the documentation for CWnd::GetDC:

Unless the device context belongs to a window class, the ReleaseDC member function must be called to release the context after painting.

Since you're not assigning the return value from GetDC to anything, there's no way for you to call ReleaseDC. Since they're not released, they build up - there's a limit to the total number of GDI objects your application can use, see GDI Objects. Once you hit that limit, things go bad very fast (Don't ask me how I know).

If this is in response to a WM_PAINT message, you shouldn't be calling GetDC in the first place. You should be using the CPaintDC object that you create. As a general rule, don't call the parent OnPaint method in your own OnPaint handler, because you can only generate a single CPaintDC.

Sign up to request clarification or add additional context in comments.

Comments

0

I found the solution. You have to initialize the DC before. So don't use GetDC()->SetPixelV(x, y, RGB(y,x,y));. Make an object before f.x CDC *pDC = GetDC(); an then use pDC->SetPixelV(x, y, RGB(y,x,y));.This is it ! Now it works like a charm :-)

Hopefully this will help someone !

4 Comments

You must be doing something else, because those two ways are exactly the same. pDC is not an object, it's a pointer to an object, and the exact same pointer returned by GetDC for e.g. GetDC()->SetPixel(...).
You can try it.Now it is working Im not lying. I declared the 'pointer' outside of my loop. And now it works ... Try it ^^
That's the difference, you moved the GetDC() outside of the loop, which is a smart idea anyway.
Or you can use BitBlt which is faster for filling the screen.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.