|
I need documents for result the vehicles routing problem with time windows, the method of resolution is ant colony optimization
baya
|
|
|
|
|
Keith,
It seems the CMemDC class is being fooled by RTL layouts so it doesn't paint the given rect. I tested it using a control that is utilizing CMemDC as it's paint buffer, and when I converted CMemDC to CDC* for testing it worked great. When using CMemDC the rect just keeps being colored grey (default bg color).
Can you please advise on how to solve this?
Stilgar.
|
|
|
|
|
Hi, with this, is it possible to set the background to a drawing? I have managed to do this by overriding onEraseBkgnd. But now, using the memdc provided, I have to override onEraseBkgnd, by returning false...
|
|
|
|
|
pDC->DPtoLP(&m_rect);
SetWindowOrg(m_rect.left, m_rect.top);
SetBrushOrg( -(m_rect.left % 8), -(m_rect.top % 8) );
} else {
|
|
|
|
|
Thank you very much for developing this piece of code. It works very well...
Greetings from Málaga, Spain.
|
|
|
|
|
Works great and very nice implementation (easy as pie).
I couldnt stand the flicker - this Rules!
|
|
|
|
|
You made flicker free drawing so easy!
For years the flickering was distubin'. That's over now.
Thank you so much.
|
|
|
|
|
|
That's a great work but how to use it in a dialog-based app?
Some people asked here the same question in the past but nobody seems to know the answer. With the following code the background of the dialog becomes white regardless of the return value of OnEraseBackground() or the functions after CMemDC.
void CTestDlg::OnPaint()
{
if (IsIconic())
{
... (default code of wizard)
}
else
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
CMemDC memDC(&dc,&rect);
//? CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
//? CDialog::OnPaint();
}
}
BOOL CTestDlg::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
}
Does anyone know a solution?
|
|
|
|
|
Do you want to draw directly on the dialog? It seems not a good idea.
If you want to avoid flicker during sizing, here are some interesting discussions:
ResizableLib
By Paolo Messina
A set of classes to ease the development of resizable windows with MFC
http://www.codeproject.com/dialog/resizablelib.asp[^]
Flicker-Free Resizing Dialog
By Andy Brown
http://www.codeguru.com/Cpp/W-D/dislog/resizabledialogs/article.php/c1917/[^]
The key part is
BOOL CResizingDialog::OnEraseBkgnd(CDC *pDC)
{
std::vector<citem>::const_iterator it;
for(it=m_Items.begin();it!=m_Items.end();it++)
{
// skip over the size icon if it's been hidden
if(it->m_bFlickerFree)
pDC->ExcludeClipRect(it->m_rcControl); // avoid flicker of each control items
}
// call the base class
CDialog::OnEraseBkgnd(pDC);
return FALSE;
}
|
|
|
|
|
ok, but it doesn't seem to be 'super' flicker free in my case ; it is better but still flickering; you probably should have each control on dialog customized to achieve flicker free repaint
in my case i use something like CEnhancedDialog which should solve flickering (and other problems) on any dialogs (they can have many different controls, and allow automatic resizing); i just wonder if there is no way to say dialog/(controls on it) to use different HDC for its painting, in this case i could use CMemDC
also it seems that in some cases if you in OnEraseBkgnd exclude controls regions for erasing, they then will not draw correctly (especialy when in 'XP style mode')
any idea how to force to use different HDC?
|
|
|
|
|
I am also waiting for a better answer.
|
|
|
|
|
thank you so much. You have saved me lots of time. Take care. J
J. Rivero
mtechno.net
|
|
|
|
|
|
i use these class, but when the rect is large, the bitmap can not be created correctly. CreateCompatibleBitmap() return a false value. i use GetlastError get the return value is 8.
i use the windowXP and the vc 6.0 sp6. Is something wrong?
thanks!
|
|
|
|
|
I have to insert a button in a CListCtrl, everything seems ok, but nothing writes when I call WM_DRAWITEM from the list control to draw the button.
the code:
ListCtrl code: (ownerdraw)
void CBotonesListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
static _TCHAR szBuff[MAX_PATH];
CRect rcItem(lpDrawItemStruct->rcItem);
UINT uiFlags = ILD_TRANSPARENT;
int nItem = lpDrawItemStruct->itemID;
BOOL bFocus = (GetFocus() == this);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
lvi.iItem = nItem;
lvi.iSubItem = 0;
lvi.pszText = szBuff;
lvi.cchTextMax = sizeof(szBuff);
lvi.stateMask = 0xFFFF; // get all state flags
GetItem(&lvi);
LV_COLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH;
//se le pone el texto que venga.
image_button.setText(szBuff);
//se tiene que llamar al Owner-draw del boton.
DRAWITEMSTRUCT istr;
if(m_item_pulsado!=nItem)
{
istr.CtlID=ID_BOTON_LISTA;
istr.CtlType=ODT_BUTTON;
istr.itemAction=ODA_DRAWENTIRE;
istr.itemState=ODS_DEFAULT;
istr.hwndItem=image_button.GetSafeHwnd();
istr.hDC=pDC->m_hDC;
image_button.GetClientRect(&istr.rcItem);
istr.rcItem.top=rcItem.top;
istr.rcItem.bottom+=rcItem.top;
istr.rcItem.left=rcItem.right;
istr.rcItem.right+=rcItem.right;
image_button.SendMessage(WM_DRAWITEM,ID_BOTON_LISTA,(long)&istr);
}
else
{
istr.CtlID=ID_BOTON_LISTA;
istr.CtlType=ODT_BUTTON;
istr.itemAction=ODA_DRAWENTIRE;
istr.itemState=ODS_SELECTED;
istr.hwndItem=image_button.GetSafeHwnd();
istr.hDC=pDC->m_hDC;
image_button.GetClientRect(&istr.rcItem);
istr.rcItem.top=rcItem.top;
istr.rcItem.bottom+=rcItem.top;
istr.rcItem.left=rcItem.right;
istr.rcItem.right+=rcItem.right;
image_button.SendMessage(WM_DRAWITEM,ID_BOTON_LISTA,(long)
&istr);
};
};
ImageButton code: (ownerdraw)
void CImageButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct )
{
if( lpDrawItemStruct->CtlType != ODT_BUTTON)
return;
CRect rectButton( lpDrawItemStruct->rcItem );
CRect rectItem( rectButton );
BOOL bFocus = lpDrawItemStruct->itemState & ODS_FOCUS;
BOOL bDisabled = ODS_DISABLED & lpDrawItemStruct->itemState;
CMemDC pDC(CDC::FromHandle(lpDrawItemStruct->hDC));
BOOL bPushed = FALSE;
if( ( lpDrawItemStruct->itemState & ODS_SELECTED ) )
bPushed = TRUE;
//Drawing Bitmap
if( m_bLoaded )
{
// Create compatible memory DC using the controls DC
CDC dcMem;
VERIFY( dcMem.CreateCompatibleDC(pDC));
BITMAP *pbmp;
// Select bitmap into memory DC.
if(!bPushed)
{
dcMem.SelectObject(&m_bitmapImage);
pbmp=&m_bitmap;
}
else
{
dcMem.SelectObject(&m_bitmapPushedImage);
pbmp=&m_bitmap_pulsado;
}
BOOL ret=pDC->StretchBlt(rectButton.left, rectButton.top, rectButton.Width(), rectButton.Height(),
&dcMem, 0, 0, pbmp->bmWidth-1, pbmp->bmHeight-1,
SRCCOPY);
if(m_con_texto)
{
Graphics gr(pDC->m_hDC);
FontFamily fontFamily(nombre_fuente);
Font m_fuente(&fontFamily, tamanyo, FontStyleBold, UnitPixel);
StringFormat stringFormat;
SolidBrush solidBrush(m_color_texto);
gr.SetTextRenderingHint(TextRenderingHintAntiAlias);
stringFormat.SetAlignment(StringAlignmentCenter);
stringFormat.SetLineAlignment(StringAlignmentCenter);
RectF rtexto(rectButton.left,rectButton.top,rectButton.right-rectButton.left,
rectButton.bottom-rectButton.top);
gr.DrawString(m_texto, -1, &m_fuente, rtexto, &stringFormat, &solidBrush);
gr.ReleaseHDC(pDC->m_hDC);
};
}
};
any help would be apreciated
|
|
|
|
|
Hi Keith,
I was using your buffer class for drawing to the Devicecontext.It worked fine until I introduced zooming.Iam zoomimg my view using the "SetWorldTransform" in "OnPrepareDc".
I have zoom percentage from 200& 500.
The problem Iam facing now is when I zoom(for example below 200%) & move vertical scroll bar,I dont get the full text of the page in the view.I get only parts of the next.
wHEN zooming,I guess the clip rectangle is not the same.How can I modify my code in "OnDraw",so that I can pass the right rect to the MemoryDc.
Hope you can give a hand....
Thanks...
Please see below the codes in my View.
*************************************
void TestView::OnDraw(CDC* pDC)
{
CSize size;
size.cx = 45;
size.cy = 45;
//Creating a temporary Dc which is my buffer class.
MemDc DC(pDC);
SetScrollSizes(MM_TEXT, size);
}
void TestView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
pDC->SetMapMode(MM_TEXT);
SetGraphicsMode(pDC->GetSafeHdc(), GM_ADVANCED);
TEXTMETRIC Metrics;
pDC->GetTextMetrics(Metrics);
Form.eM11 = 0.01 * zoom;//Member variable of my class & can be 200,500
Form.eM21 = 0;
Form.eDx = 0;
Form.eM12 = 0;
Form.eM22 = 0.01 * zoom;
Form.eDy = 0;
SetWorldTransform(pDC->GetSafeHdc(), &Form);
LOGFONT LogFont;
Font.GetLogFont(&LogFont);
CScrollView::OnPrepareDC(pDC, pInfo);
}
-- modified at 7:14 Wednesday 28th September, 2005
|
|
|
|
|
Dear Keith,
First of all a big thanks for sharing your CMemDC class! It's great!
I've been using CMemDC for all the painting of my views, but I have encountered this problem of getting a strip of horizontal streaks right across the top of the screen when I run my application. I suspect it's something wrong with my drawing code for the bitmaps I display on the screen. Can I ask whether the following, when using CMemDC as the destination CDC, is correct for blitting the bitmaps on the screen? Your help is greatly appreciated!
=========================================================================
void MyView::drawBitmaps(CDC* pDC)
{
// Note: pDC is a CMemDC* of the DC passed to the view's OnDraw(pDC)
// --------------------- draw the baby bitmap --------------------- //
BITMAP bmpInfo;
m_bmpBaby.GetBitmap(&bmpInfo);
// Create an in-memory DC compatible with the
// display DC we're using to paint
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
// Select the bitmap into the in-memory DC
CBitmap* pOldBitmap = dcMemory.SelectObject(&m_bmpBaby);
// Set position of the bitmap
int nX = m_babyPicRect.left;
int nY = m_babyPicRect.top;
int nW = m_babyPicRect.Width();
int nH = m_babyPicRect.Height();
// Copy the bits from the in-memory DC into CMemDC
pDC->StretchBlt(nX, nY, nW, nH, &dcMemory, 0, 0, bmpInfo.bmWidth,
bmpInfo.bmHeight, SRCCOPY);
dcMemory.SelectObject(pOldBitmap);
// ------------------- draw the electrodes bitmap ---------------------
m_bmpElectrodeLoc.GetBitmap(&bmpInfo);
// Select the bitmap into the in-memory DC
pOldBitmap = dcMemory.SelectObject(&m_bmpElectrodeLoc);
// Set position of the bitmap
nX = m_elecPosPicRect.left;
nY = m_elecPosPicRect.top;
nW = m_elecPosPicRect.Width();
nH = m_elecPosPicRect.Height();
pDC->StretchBlt(nX, nY, nW, nH, &dcMemory, 0, 0, bmpInfo.bmWidth,
bmpInfo.bmHeight, SRCCOPY);
dcMemory.SelectObject(pOldBitmap);
}
==========================================================================
What happens is that my application requires the view to repaint when OnTimer() is called, because I need to display certain information on a timely basis. drawBitmaps() is thus called every few seconds. I do not see the corrupted colour strip appearing the first few times, but it starts after one to two minutes, then reoccurs every so often.
My apologies for such a long question! Thanks in advance!!
Kind regards,
Isa
|
|
|
|
|
Would someone please be able to help me out on this one? Is my problem the same as the one mentioned in the 'streaks and smudging' thread?
Thanks in advance...
|
|
|
|
|
Hey, thanks for the code, this has been a great tool to get rid of the flicker with. Unfortunately, a new problem has arisen: whenever i move a window or a dialog across the view, it'll leave random streaks vertical or horizontal to the direction the window/dialog is dragged across it. There's also a bit of smudging of characters as well. How do I fix this?
|
|
|
|
|
I can honestly say I've never run across this behavior. However, if my application was doing this I would look at my drawing code. It sounds to me like you aren't redrawing the entire clip rectangle for some reason, which is leaving the artifacts you are describing.
Please let me know what you find out.
Thanks,
Keith Rule
|
|
|
|
|
I have found the problem occurs in my app as well. Essentially when a dilog box is overlaid on CView drawn using CMemDC and the dialog box is moved in quick jerks it leaves a thin blue line (the colour of the border of the dialog box). The problem seems to go away when you specify the correct rect in CMemDC(DC*, RECT*) ctor.
If winter comes is spring far behind? - (PBShelley -Ode to the West Wind)
|
|
|
|
|
I've looked at this and modified your CMemDC ctor as follows:
CMemDC(CDC* pDC, const CRect* pRect = NULL) : CDC()
//pRect is in device co-ordinates
//printing stuff removed as I didn't need it
{
ASSERT(pDC != NULL);
// Some initialization
m_pDC = pDC;
m_oldBitmap = NULL;
// Get the rectangle to draw
CRect lrect;
if (pRect == NULL) {
pDC->GetClipBox(&m_rect);
lrect=m_rect;
pDC->LPtoDP(&lrect);
} else {
lrect = *pRect;
m_rect=lrect;
pDC->DPtoLP(&m_rect);
}
//lrect is in device units
//m_rect is in logical units
CreateCompatibleDC(pDC);
m_bitmap.CreateCompatibleBitmap(pDC, lrect.Width(),lrect.Height());
m_oldBitmap = SelectObject(&m_bitmap);
SetMapMode(pDC->GetMapMode());
SetWindowExt(pDC->GetWindowExt());
SetViewportExt(pDC->GetViewportExt());
//pDC->DPtoLP(&m_rect);
SetWindowOrg(m_rect.left, m_rect.top);
// Fill background
FillSolidRect(m_rect, pDC->GetBkColor());
}
Now it seems OK.
chakra
"Some people will do anything for money...Even work"
|
|
|
|
|
yeah, i have the same situation as you have, if no rect specified in ctor, there would be streaks if jerk the the drawing window from unhiding.
one is the other who absorbs the thoughts of others
|
|
|
|
|
I set window extent, viewport exten and window origin.
good luck
chakra
If winter comes is spring far behind? - (PBShelley -Ode to the West Wind)
|
|
|
|
|