Click here to Skip to main content
15,902,938 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all I am working with a CHtmlEditCtrl in MFC. I want to draw some random rectangles and lines inside a function handling right click event.

What I have tried:

The ChtmlEditCtrl control is created from static using this snippet:
C++
    bool CHtmlEditCtrlEx::CreateFromStatic( UINT nID, CWnd* pParent ) {
    	CStatic wndStatic;
    	if ( !wndStatic.SubclassDlgItem(nID, pParent)) {
    		return false;
    	}
    	CRect rc;
    	wndStatic.GetWindowRect( &rc );
    	pParent->ScreenToClient( &rc );
    	if (Create( 0, (WS_CHILD | WS_VISIBLE), rc, pParent, nID, 0 )) {
    		...
    }

Then I override the CWnd::pretranslate() function as thus:
  

      CClientDC dcc(this);
        switch (pMsg->message) {
        
        	case WM_RBUTTONUP:	// Right-click
                // Just some dummy values
        		DrawSquigly(dcc, 600, 240, 20);
                break;
        
        }

the DrawSquigly() function is defined as thus:

    void CHtmlEditCtrlEx::DrawSquigly(CDC &dcc, int iLeftX, int iWidth, int iY)
    {
    	CAMTrace trace;
    	trace.Trace("Drawing Squiggly");
    	//dcc.TextOut(10, 10, CString(_T("I used a client DC!")));
        		
    	CPen * oldPen;
    	CBrush * oldBrush;
    	oldPen = (CPen *) dc.SelectStockObject(WHITE_PEN);
    	dcc.MoveTo(5,10);
    	dcc.LineTo(80, 10);
    	dcc.SelectObject(oldPen);
    
    	//GDI 002_2: Create custom pen with different Line thickness.
    	CPen thick_pen(PS_SOLID, 3, RGB(0,255,0));
    	oldPen = dc.SelectObject(&thick_pen);
    	dcc.MoveTo(5, 20);
    	dcc.LineTo(80,20);
    	dcc.SelectObject(oldPen);
    
    	//GDI 002_3: Create a Rectangle now
    	dcc.Draw3dRect(5,30,80,70, RGB(25,25,255), RGB(120,120,120));
    
    	//GDI 002_4: Create a Brush that we can use for filling the 
    	// closed surfaces
    	CBrush brush(RGB(255,0,255));
    	oldBrush = dc.SelectObject(&brush);
    	dcc.Rectangle(5,110,80,140);
    	dcc.SelectObject(oldBrush);
    
    	//GDI 002_5: Hatch Brush is useful to apply a pattern in stead 
    	//of solid fill color
    	CBrush* hatBrush = new CBrush();
    	hatBrush->CreateHatchBrush(HS_CROSS, RGB(255,0,255));
    	oldBrush = dc.SelectObject(hatBrush);
    	dcc.FillRect(new CRect(5,160,80,190), hatBrush);
    	dcc.SelectObject(oldBrush);
    }

but no drawing happens when I right click. I think I am missing something especially because I am new to MFC.

I have added a trace to the top of the event handler to be sure that the function is getting called and it is.

Can anyone please point me the right direction?
Posted
Updated 22-Mar-16 1:17am
v2
Comments
Richard MacCutchan 4-Mar-16 5:59am    
I think you are doing things in the wrong place. All drawing in Windows should be done in response to a WM_PAINT message. If you draw on a control anywhere else then whatever you render is likely to be erased as soon as the control (Window) receives the next WM_PAINT message. I am not sure why you chose this particular control but maybe you should just use a basic Window.
Ashiru Ali 7-Mar-16 4:50am    
Hi, According to MSDN "The system sends an internal WM_PAINT message only once. After an internal WM_PAINT message is returned from GetMessage or PeekMessage or is sent to a window by UpdateWindow, the system does not post or send further WM_PAINT messages until the window is invalidated or until RedrawWindow is called again with the RDW_INTERNALPAINT flag set." in my understanding to get a DC for this message, the CPaintDC is more appropriate. it happens only once (The window is drawn or specifically redrawn)
Richard MacCutchan 7-Mar-16 6:53am    
Well if it works for you that is fine.
Arthur V. Ratz 21-Mar-16 2:31am    
5.
[no name] 9-Mar-16 16:16pm    
At some point, Windows will send a WM_PAINT to the control. It will erase any drawing done by your pre-translate code above.

A more ideal approach would be to have the control draw to a memory DC. You would have to override the WM_PAINT handler (and likely the WM_ERASEBKGND too), cause control to draw itself to a memory DC, add your own "owner" drawings to the memory DC, and then BitBlt the memory DC to a screen DC.

Some controls can tolerate being diverted to a memory DC. Some do not.

1 solution

Your drawing code belongs in the OnPaint() function. At first make the default call and than your stuff.
C++
void CHtmlEditCtrlEx::OnPaint()
{
  CWnd::OnPaint();

  //here comes your drawing code
  DrawSquigly(...);
}


For controlling the drawing you should use a member variable activated in the WM_RBUTTONUP message.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900