Potential Leak of an Object while using CGGraphics in a Loop - memory-leaks

I don't get it, how to solve the problem?
I used "analyze" cause my program crashes due memory problems and the first one of seven similar notations is "Potential Leak of an Object stored into signalline" conected to CGContextStrokePath(signalContext);
- (void)drawHorizoLines{
for(int i = 1; i < self.frame.size.width/_sw;i++){
CGContextRef signalContext = UIGraphicsGetCurrentContext();
CGMutablePathRef signalLine = CGPathCreateMutable();
CGContextSetLineWidth(signalContext, 0.4); //LineWidth
CGContextBeginPath(signalContext);
CGContextSetStrokeColorWithColor(signalContext, [UIColor purpleColor].CGColor);
CGPathMoveToPoint(signalLine, 0, 0, i*_rowHeigth + _sbd/2);//Startpoint
CGPathAddLineToPoint(signalLine, 0, self.frame.size.width, i*_rowHeigth + _sbd/2);
CGContextAddPath(signalContext, signalLine);
//CGContextClosePath(signalLine); didnt work
CGContextStrokePath(signalContext);
//CGContextRelease(signalContext); didnt work
}
}

According to CoreFoundation Ownership Policy, you are the owner of signalLine, which came from a Create function. You must call CFRelease(signalLine) to release it.
The safest way to do this is to ensure it is not NULL first:
if (signalLine) CFRelease(signalLine);

Related

Why don't I see any tree item

Visual Studio MFC library in 2015
I've been working on this
And it's not working for me
I don't see any item
There are many older examples
I think it doesn't work on vc2015 ?
Here is the code
void CMFCApplication67Dlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT
*pResult)
{
// TODO: Add your control notification handler code here
TVINSERTSTRUCT tvInsert;
tvInsert.hParent = NULL;
tvInsert.hInsertAfter = NULL;
tvInsert.item.mask = TVIF_TEXT;
tvInsert.item.pszText = _T("United States");
HTREEITEM hCountry = m_l.InsertItem(&tvInsert);
HTREEITEM hPA = m_l.InsertItem(TVIF_TEXT,
_T("Pennsylvania"), 0, 0, 0, 0, 0, hCountry, NULL);
HTREEITEM hWA = m_l.InsertItem(_T("Washington"),
0, 0, hCountry, hPA);
m_l.InsertItem(_T("Pittsburgh"), hPA, TVI_SORT);
m_l.InsertItem(_T("Harrisburg"), hPA, TVI_SORT);
m_l.InsertItem(_T("Altoona"), hPA, TVI_SORT);
m_l.InsertItem(_T("Seattle"), hWA, TVI_SORT);
m_l.InsertItem(_T("Kalaloch"), hWA, TVI_SORT);
m_l.InsertItem(_T("Yakima"), hWA, TVI_SORT);
The question differently.
When I drag a control from the Toolbox and wooden I copy the code examples I gave are supposed to work or what needs to be done
Set the parent item to TVI_ROOT, not null. Also, from what I can tell, your code is only called when the selection in the tree changes; you'll probably want to do the whole InsertItem stuff in CMFCApplication67Dlg::OnInitDialog.
Now I get it.
Need to boot in the "OnInitDialog" function Like here.
I looked in the "OnInitDialog" classes view
Put name and initialization code works! thanks to all who helped!
My mistake.Press double click on the tree where I rebooted. CPP no in "OnInitDialog"
I wrote that if someone will mistakenly call him might help him. Thanks again

How to utilize DirectX/DirectDraw to accelerate animation of a hosted windowless ActiveX control

I have a standard GDI win32 application. I have a component which can host windowless ActiveX controls (we use this typically for Flash) by utilizing the IOleInPlaceSiteWindowless/IOleInPlaceObjectWindowless pair of interfaces and therefore calling IViewObject::Draw whenever the hosted control calls back into InvalidateRect. This component is generally modeled after this article: http://www.codeguru.com/cpp/com-tech/activex/controls/article.php/c12229/Transparent-Flash-Control-in-Plain-C.htm
Now my application targets some older hardware and I'm seeing some performance problems with this approach that I don't see when running the same ActiveX control in Internet Explorer. In fact, using process monitor, I'm able to see that IE is using the GPU to some degree to render while my application is not. This has led me to discover that IE is likely using DirectDraw under the covers the achieve the better performance.
So I've taken a stab at doing this within my application, but I'm not seeing anything drawn on the screen. My DirectX/DirectDraw knowledge is nearly nil so that may have something to do with it, but here is what I'm trying to do. Maybe someone can see what I'm doing wrong and get me to where I need to be (note that I am just playing around which is why there is no error handling):
I create my layered window
ivhWnd = CreateWindowEx(WS_EX_LAYERED,
L"MyWndClass",
NULL,
WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
ivhParentWindow,
( HMENU )NULL,
ivhAppInstance,
( LPVOID )NULL );
I initialize DirectDraw and create an off screen surface:
DirectDrawCreateEx(NULL, (LPVOID*)&pivDD, IID_IDirectDraw7, NULL);
pivDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
DDSURFACEDESC2 tvSurfDesc;
ZeroMemory(&tvSurfDesc, sizeof(DDSURFACEDESC2));
tvSurfDesc.dwSize = sizeof(DDSURFACEDESC2);
tvSurfDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
tvSurfDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
tvSurfDesc.dwWidth = 320;
tvSurfDesc.dwHeight = 340;
HRESULT tvHR = pivDD->CreateSurface((LPDDSURFACEDESC)&tvSurfDesc, (LPDIRECTDRAWSURFACE*)&pivPrimarySurface, NULL);
LPDIRECTDRAWCLIPPER ptvClipper;
pivDD->CreateClipper(0, &ptvClipper, NULL);
ptvClipper->SetHWnd(0, ivhInternalMsgWindow);
pivPrimarySurface->SetClipper(ptvClipper);
Similar to my initial implementation where I called IViewObject::Draw whenever InvalidateRect is called by the control; I now do basically the same, but utilizing the DC for my DDraw surface instead of a compatible bitmap:
RECT rTotal;
::GetClientRect(ivhWnd, &rTotal);
HDC tvhDC;
pivPrimarySurface->GetDC(&tvhDC);
HRESULT tvHR = OleDraw(ivViewObject, DVASPECT_TRANSPARENT, tvhDC, &rTotal);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.AlphaFormat = AC_SRC_ALPHA;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255;
UpdateLayeredWindow(ivhWnd, NULL, NULL, NULL, tvhDC, NULL, 0, &bf, ULW_ALPHA);
Not sure what I'm doing wrong, and I'm basically stuck. Any help would be appreciated.

Display Text on MFC Based Application

I'm a little new to using MFC and VC++ as such, but I'm doing this as part of a Course and i Have to stick to VC++.
http://www.cprogramming.com/tutorial/game_programming/same_game_part1.html
This is the tutorial I have been following to make a simple samegame. However when i try to display score, the score is getting displayed Underneath or outside my application window, even though I've displayed score before calling updateWindow(). I've tried various methods but I am kinda lost here.
Here is the code I'm using to Display the score:
void CSameGameView::updateScore()
{
CSameGameDoc* pDoc = GetDocument();
CRect rcClient, rcWindow;
GetClientRect(&rcClient);
GetParentFrame()->GetWindowRect(&rcWindow);
int nHeightDiff = rcWindow.Height() - rcClient.Height();
rcScore.top=rcWindow.top + pDoc->GetHeight() * pDoc->GetRows() + nHeightDiff;
rcScore.left=rcWindow.left + 50;
rcScore.right=rcWindow.left + pDoc->GetWidth() - 50;
rcScore.bottom=rcScore.top + 20;
CString str;
double points = Score::getScore();
str.Format(_T("Score: %0.2f"), points);
HDC hDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
COLORREF clr = pDoc->GetBoardSpace(-1, -1); //this return background colour
pDC->FillSolidRect(&rcScore, clr);
DrawText(hDC, (LPCTSTR) str, -1, (LPRECT) &rcScore, DT_CENTER);
}
Thank you for any help and I'm sorry if the question doesn't make sense or in ambiguous.
There are several problems with your code:
1. The hDC you are creating is going to have coordinates relative to the desktop window. To paint text in your window, use CClientDC like this: CClientDC dc(this); (see http://msdn.microsoft.com/en-US/library/s8kx4w44%28v=vs.80%29.aspx)
2. The code you have will leak a DC every time the function is called. The method in #1 will fix that.
3. Your paint code should be done in the CView::OnDraw. There you get a DC passed to you and you don't have to worry about creating one with CClientDC. Set the variables you want to draw (e.g. your points or score), store them as class members and draw them in CView::OnDraw.
Don't do the drawing in your updateScore method.
Make sense? Hang in there!

Brightness method shows "Out of memory" exception

To change brightness of an image in c#.net 4 i have used the following method.
public void SetBrightness(int brightness)
{
imageHandler.RestorePrevious();
if (brightness < -255) brightness = -255;
if (brightness > 255) brightness = 255;
ColorMatrix cMatrix = new ColorMatrix(CurrentColorMatrix.Array);
cMatrix.Matrix40 = cMatrix.Matrix41 = cMatrix.Matrix42 = brightness / 255.0F;
imageHandler.ProcessBitmap(cMatrix);
}
internal void ProcessBitmap(ColorMatrix colorMatrix)
{
Bitmap bmap = new Bitmap(_currentBitmap.Width, _currentBitmap.Height)
ImageAttributes imgAttributes = new ImageAttributes();
imgAttributes.SetColorMatrix(colorMatrix);
Graphics g = Graphics.FromImage(bmap);
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(_currentBitmap, new Rectangle(0, 0, _currentBitmap.Width,
_currentBitmap.Height), 0, 0, _currentBitmap.Width,
_currentBitmap.Height, GraphicsUnit.Pixel, imgAttributes);
_currentBitmap = (Bitmap)bmap.Clone();
}
If brightness is changed several times then "Out of memory" exception is shown. I have tried to use "Using block" but went in vein.
Any ideas?
please see the link
http://www.codeproject.com/Articles/227016/Image-Processing-using-Matrices-in-Csharp
and suggest if any types of optimization is possible in the methods (Rotation, brightness, crop and undo).
I have downloaded the projects from CodeProject and I have fixed the memory leak. You need to dispose the Graphics object and the _currentBitmap image before you override it. Also, you need to stop using .Clone.
If you replace the contents of the ProcessBitmap function with this code, the memory leak is gone:
internal void ProcessBitmap(ColorMatrix colorMatrix)
{
Bitmap bmap = new Bitmap(_currentBitmap.Width, _currentBitmap.Height);
ImageAttributes imgAttributes = new ImageAttributes();
imgAttributes.SetColorMatrix(colorMatrix);
using (Graphics g = Graphics.FromImage(bmap))
{
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(_currentBitmap, new Rectangle(0, 0, _currentBitmap.Width, _currentBitmap.Height), 0, 0, _currentBitmap.Width, _currentBitmap.Height, GraphicsUnit.Pixel, imgAttributes);
}
_currentBitmap.Dispose();
_currentBitmap = bmap;
}
Also, here are some tips for further optimization:
Stop using .Clone(). I have seen the code, and it uses .Clone() everywhere. Don't clone objects unless really necessary. In image processing, you need a lot of memory to store large image files. You need to make as much processing as you can in-place.
You can pass Bitmap objects by reference between methods. You can improve performance and reduce the memory cost that way.
Always use using blocks when working with Graphics objects.
Call .Dispose() on the Bitmap objects when you're sure you don't need them anymore

Resize CATextLayer to fit text on iOS

All my research so far seems to indicate it is not possible to do this accurately. The only two options available to me at the outset were:
a) Using a Layout manager for the CATextLayer - not available on iOS as of 4.0
b) Use sizeWithFont:constrainedToSize:lineBreakMode: and adjust the frame of the CATextLayer according to the size returned here.
Option (b), being the simplest approach, should work. After all, it works perfectly with UILabels. But when I applied the same frame calculation to CATextLayer, the frame was always turning out to be a bit bigger than expected or needed.
As it turns out, the line-spacing in CATextLayers and UILabels (for the same font and size) is different. As a result, sizeWithFont (whose line-spacing calculations would match with that of UILabels) does not return the expected size for CATextLayers.
This is further proven by printing the same text using a UILabel, as against a CATextLayer and comparing the results. The text in the first line overlaps perfectly (it being the same font), but the line-spacing in CATextLayer is just a little shorter than in UILabel. (Sorry I can't upload a screenshot right now as the ones I already have contain confidential data, and I presently don't have the time to make a sample project to get clean screenshots. I'll upload them later for posterity, when I have the time)
This is a weird difference, but I thought it would be possible to adjust the spacing in the CATextLayer by specifying the appropriate attribute for the NSAttributedString I use there, but that does not seem to be the case. Looking into CFStringAttributes.h I can't find a single attribute that could be related to line-spacing.
Bottomline:
So it seems like it's not possible to use CATextLayer on iOS in a scenario where the layer is required to fit to its text. Am I right on this or am I missing something?
P.S:
The reason I wanted to use CATextLayer and NSAttributedString's is because the string to be displayed is to be colored differently at different points. I guess I'd just have to go back to drawing the strings by hand as always....of course there's always the option of hacking the results from sizeWithFont to get the proper line-height.
Abusing the 'code' tags a little to make the post more readable.
I'm not able to tag the post with 'CATextLayer' - surprisingly no such tags exist at the moment. If someone with enough reputation bumps into this post, please tag it accordingly.
Try this:
- (CGFloat)boundingHeightForWidth:(CGFloat)inWidth withAttributedString:(NSAttributedString *)attributedString {
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString( (CFMutableAttributedStringRef) attributedString);
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(inWidth, CGFLOAT_MAX), NULL);
CFRelease(framesetter);
return suggestedSize.height;
}
You'll have to convert your NSString to NSAttributedString. In-case of CATextLayer, you can use following CATextLayer subclass method:
- (NSAttributedString *)attributedString {
// If string is an attributed string
if ([self.string isKindOfClass:[NSAttributedString class]]) {
return self.string;
}
// Collect required parameters, and construct an attributed string
NSString *string = self.string;
CGColorRef color = self.foregroundColor;
CTFontRef theFont = self.font;
CTTextAlignment alignment;
if ([self.alignmentMode isEqualToString:kCAAlignmentLeft]) {
alignment = kCTLeftTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentRight]) {
alignment = kCTRightTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentCenter]) {
alignment = kCTCenterTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentJustified]) {
alignment = kCTJustifiedTextAlignment;
} else if ([self.alignmentMode isEqualToString:kCAAlignmentNatural]) {
alignment = kCTNaturalTextAlignment;
}
// Process the information to get an attributed string
CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
if (string != nil)
CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), (CFStringRef)string);
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTForegroundColorAttributeName, color);
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTFontAttributeName, theFont);
CTParagraphStyleSetting settings[] = {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTParagraphStyleAttributeName, paragraphStyle);
CFRelease(paragraphStyle);
NSMutableAttributedString *ret = (NSMutableAttributedString *)attrString;
return [ret autorelease];
}
HTH.
I have a much easier solution, that may or may not work for you.
If you aren't doing anything special with the CATextLayer that you can't do a UILabel, instead make a CALayer and add the layer of the UILabel to the CALayer
UILabel*label = [[UILabel alloc]init];
//Do Stuff to label
CALayer *layer = [CALayer layer];
//Set Size/Position
[layer addSublayer:label.layer];
//Do more stuff to layer
With LabelKit you don't need CATextLayer anymore. No more wrong line spacing and wider characters, all is drawn in the same way as UILabel does, while still animated.
This page gave me enough to create a simple centered horizontally CATextLayer : http://lists.apple.com/archives/quartz-dev/2008/Aug/msg00016.html
- (void)drawInContext:(CGContextRef)ctx {
CGFloat height, fontSize;
height = self.bounds.size.height;
fontSize = self.fontSize;
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 0.0, (fontSize-height)/2.0 * -1.0);
[super drawInContext:ctx];
CGContextRestoreGState(ctx);
}

Resources