• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 455
  • Last Modified:

How to I convert this C++ to Delphi?

Hi Experts,

Can somebody convert following code to delphi? So I can use is tp replace color of a HBitmap
Thanks in advance!
Best regards,
Ahamed
HBITMAP bmpReplaceColor(HBITMAP hbm, COLORREF oldColor, COLORREF newColor)
{
	CDC hdcOld = CreateCompatibleDC(NULL);
	CDC hdcNew = CreateCompatibleDC(NULL);
	CBitmapHandle _hbmOld = NULL, _hbmOld2 = NULL, bmOld = hbm;
	BOOL bOK=false;
	CBitmap bmNew = NULL;
	SIZE bmpDim = { 0 };

	bmOld.GetSize(bmpDim);
	_hbmOld = hdcOld.SelectBitmap(bmOld);

	bmNew.CreateCompatibleBitmap(hdcOld, bmpDim.cx, bmpDim.cy);
	ATLASSERT(!bmNew.IsNull());//error checking!!!

	_hbmOld2 = hdcNew.SelectBitmap(bmNew);
       //"transparent" color background
	hdcNew.FillSolidRect(0,0,bmpDim.cx, bmpDim.cy, newColor);
	bOK = hdcNew.TransparentBlt(0,0,bmpDim.cx,bmpDim.cy, hdcOld, 0,0,bmpDim.cx,bmpDim.cy, oldColor);

	hdcOld.SelectBitmap(_hbmOld);
	hdcNew.SelectBitmap(_hbmOld2);
	if (bOK == FALSE) bmNew.DeleteObject();
return bmNew.Detach();
}

Open in new window

0
ahamedmohideen
Asked:
ahamedmohideen
1 Solution
 
epasquierCommented:
do you want an exact match of function signature (bitmap handle in and out) or would you prefer a more delphi approach (TBitmap in and out) ?
0
 
ahamedmohideenAuthor Commented:
Yes please exact match.  But also curios to know the delpi aproach.

Thanks in advance.
0
 
epasquierCommented:
Delphi approach :
function ReplaceColor(const BMP:TBitmap;OldColor,NewColor:TColor):TBitmap;
Var
 BMP2:TBitmap;
begin
 BMP2:=TBitmap.Create;
 try
  BMP2.Assign(BMP);
  BMP2.TransparentColor:=OldColor;
  BMP2.Transparent:=True;
  Result:=TBitmap.Create;
  Result.PixelFormat:=BMP.PixelFormat;
  Result.Canvas.Brush.Color:=NewColor;
  Result.Width:=BMP.Width;
  Result.Height:=BMP.Height;
  Result.Canvas.Draw(0,0,BMP2);
 finally
  BMP2.Free;
 end;
end;

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ahamedmohideenAuthor Commented:
Thanks for your help and code. But please give a solution where I get a HBitmap.

Thanks alot
0
 
epasquierCommented:
I'm afraid I'm not confident enough with the HBITMAP and WinAPI inner workings to do a strict conversion of the code you provided. This is C++, so I would have to know what is hidden in CDC class.

Anyway, I strongly advise you, when you code in Delphi, and you have a Delphi solution for what you want, that is good enough performance-wise (which is the case here), then do not look for a solution that would rely too heavily on platform-specific API.
You can bet that this code will work in all Delphi versions to come, compiled for Mac or Linux or whatever else when Delphi will officially support those. You couldn't say as much if your code rely on direct calls of Win API.
0
 
ahamedmohideenAuthor Commented:
Yes you are right. But my problem is, I need to supply the HBitmap to a foreign library.

Thanks alot.
0
 
epasquierCommented:
I have a *working* solution by I know I can't manage the memory object correctly. There are probably some leaking memory the size of TBitmap wrapper around windows HBITMAP, for each call.

Those HBITMAP handles are a bit complex to use directly because of the way they are allocated in memory. The TBitmap object is very helpful to simplify that handling. But when I free a TBitmap it frees also the HBitmap associated to it (even if I save it before, I loose the important data).

So this solution should not be used, instead try to find a way in your application to use only TBitmap with the solution above.
This is just a "demo" solution :
function ReplaceColorH(hBMP:HBITMAP;OldColor,NewColor:TColor):HBITMAP;
Var
 BMP,BMP2:TBitmap;
begin
 BMP:=TBitmap.Create;
 BMP.Handle:=hBMP;
 BMP2:=ReplaceColor(BMP,OldColor,NewColor);
 Result:=BMP2.Handle;
 BMP.Free;
// BMP2.Free; // HERE ! PROBLEM : I cannot free it or the handle is lost...
end;

Open in new window

0
 
ahamedmohideenAuthor Commented:
Well I thought of this solution too. But the problem is as you said the memory leak. So There should be a way to detach the HBITMAP from TBITMAP. I looking my self.
Please try to dig abit deeper.

Thanks alot.
Ahamed
0
 
epasquierCommented:
oh, if I understand you correctly, you have to SUPPLY the hBITMAP to another library, so you could use the first function , and give Result.Handle to your other lib ?

procedure TForm1.ProcessBMP(BMP:TBitmap);
Var BMP2:TBitmap;
begin
 BMP2:=ReplaceColor(BMP,clRed,clYellow);
 MyOtherLibFunction( BMP2.Handle ); // apply some effects for example
// Do something else with the result in BMP2, like painting it somewhere
 BMP2.Free; // Then free the temp object when used.
end;
0
 
ahamedmohideenAuthor Commented:
Yes but after I give the Handle to the library ist ok to free the Result?

Thanks alot.
0
 
ThievingSixCommented:
No, the handle will get closed if you free the TBitmap.
0
 
ahamedmohideenAuthor Commented:
Well then If I dont free the Bitmap there  will be a memory leak?

Thanks alot.
0
 
epasquierCommented:
it all depends of what your lib does with the handle.
- If it treats it immediately, then after the call you can free the Bitmap (so the handle as well) when you no longer need it.
- if it keeps it for later use, then you'll have to free the bitmap only after the lib as finished using it (there should be an 'end of treatment' function in the library also, you Bmp.free should occur just after)
0
 
Ephraim WangoyaCommented:

@epasquire

Congrats for hitting the 1million points mark

Now I may just get enough motivation to start answering questions again
0
 
epasquierCommented:
Thank you ewangoya ! Yes it is quite a milestone. Next rank is just impossible in Delphi Zone I'm afraid.
If you want more motivation : you have a bit less than 3 month to break my last year record of ~660pts.
Then, you'll be halfway to the 1M pts, so maybe 3 more month of hard work. Isn't that a good challenge ?
0
 
ahamedmohideenAuthor Commented:
Nice of you to congradulate each other but can you move such comment to some where else and dont disturb my post.

Thanks alot.
0
 
epasquierCommented:
ahamedmohideen:
yes, sorry for pep talking in your post. The thing is there is no way to communicate directly between experts, so we do that sometimes in question threads. Most askers find it funny and often takes part of the discussion as well. But I understand you'd rather have a solution.

I guess I have given you the best answer possible for the moment, as you haven't answered if what I supposed about the way you need to use this external library, is true or not.
0
 
ahamedmohideenAuthor Commented:
Please bare with me I am trying somethings out then I will answer your question.
0
 
ahamedmohideenAuthor Commented:
Thanks alot this thing works. It seems to be that library creates its own copy of the image. So after passing the Bitmap.Handle. I was able to free it without any problems.
Thanks for your help once again.
0
 
ahamedmohideenAuthor Commented:
Thanks for quick help.
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now