PDA

Click to See Complete Forum and Search --> : GetObjectAPI with DC


Sastraxi
Nov 8th, 2002, 05:34 PM
Can it be done? I want to get a Bitmap object (so I can do the bitmap array manipulations) but I need to get it with the DC that I have. How would this be done?

Valkan
Nov 12th, 2002, 01:22 AM
use the GetCurrentObject API

Private Declare Function GetCurrentObject Lib "gdi32" (ByVal hdc As Long, ByVal uObjectType As Long) As Long
Private Const OBJ_BITMAP = 7

Private Function GetBmpHandle(hdc As Long)

GetBmpHandle = GetCurrentObject(hdc, OBJ_BITMAP)

End Function

Sastraxi
Nov 12th, 2002, 06:32 AM
Thanks! Do you know how to get a bitmap long into a bitmap type?

Valkan
Nov 12th, 2002, 08:29 AM
Well, yes :)

once you retreive the handle of the current bitmap object in your dc, just use the GetObject API to get your BITMAP type. Your code could now look like this :


dim hBmp as long
dim myBmp as BITMAP

hBmp = GetCurrentObject(myHdc, OBJ_BITMAP)
GetObject hBmp, len(myBmp), myBmp

Sastraxi
Nov 12th, 2002, 05:47 PM
Wow. I need to learn more API, no? ;)
Cheers for all the help!

Valkan
Nov 13th, 2002, 12:09 AM
Just glad I could help... damn, I think I'm getting addicted to this forum :D Anyway, wanna know my API secret ? :) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/windows_api_reference.asp If you are able to deal with learning from c++ examples, all your API questions will be answered there!

- Valkan

Sastraxi
Nov 13th, 2002, 06:30 AM
How come whenever I go to the MSDN now, it comes up with a stupid list?

Valkan
Nov 13th, 2002, 07:35 AM
Originally posted by Sastraxi
How come whenever I go to the MSDN now, it comes up with a stupid list?

Huh!?!... what list are you talking about?

Sastraxi
Nov 13th, 2002, 03:00 PM
After clicking your link (or any link on the MSDN for that matter), it comes up with a list that contains these links (no formatting, no text formatting, just a white page with these links):Welcome to the MSDN Library
Welcome to the MSDN Library
Component Development
Data Access
Development (General)
Enterprise Development
Graphics and Multimedia
Messaging and Collaboration
Mobile and Embedded Development
.NET Development
.NET Development
Networking and Directory Services
Office Solutions Development
Security
Security
Setup and System Administration
User Interface Design and Development
User Interface Design and Development
Visual Tools and Languages
Web Development
Windows Development
XML Web Services
XML Web Services
MSDN Library ArchiveWeird, no?

Sastraxi
Nov 13th, 2002, 03:28 PM
Hmm.. It's not working... It's retrieving everything correctly, and I'd look to the MSDN for advice, but as I mentioned, it's not working for me >_<. Here's what my function looks like:Public Function AlphaBltFast(ByVal hDest As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrc As Long, ByVal hAlpha As Long, ByVal xSrc As Long, ByVal ySrc As Long)
Dim I As Long
Dim J As Long

Dim TempR As Long
Dim TempG As Long
Dim TempB As Long

Dim AlphaVal As Long
Dim SrcVal As Long
Dim DestVal As Long

Dim dBitmap As Long
Dim dBMP As BITMAP
Dim dPic() As Byte
Dim dSA As SAFEARRAY2D

Dim sBitmap As Long
Dim sBMP As BITMAP
Dim sPic() As Byte
Dim sSA As SAFEARRAY2D

Dim aBitmap As Long
Dim aBMP As BITMAP
Dim aPic() As Byte
Dim aSA As SAFEARRAY2D

Dim nSrcX As Long
Dim nSrcY As Long

dBitmap = GetCurrentObject(hDest, OBJ_BITMAP)
sBitmap = GetCurrentObject(hSrc, OBJ_BITMAP)
aBitmap = GetCurrentObject(hAlpha, OBJ_BITMAP)

GetObject dBitmap, Len(dBMP), dBMP
GetObject sBitmap, Len(sBMP), sBMP
GetObject aBitmap, Len(aBMP), aBMP

dSA.cbElements = 1
dSA.cDims = 2
dSA.Bounds(0).lLbound = 0
dSA.Bounds(0).cElements = dBMP.bmHeight
dSA.Bounds(1).lLbound = 0
dSA.Bounds(1).cElements = dBMP.bmWidthBytes
dSA.pvData = dBMP.bmBits

CopyMemory ByVal VarPtrArray(dPic), VarPtr(dSA), 4

sSA.cbElements = 1
sSA.cDims = 2
sSA.Bounds(0).lLbound = 0
sSA.Bounds(0).cElements = sBMP.bmHeight
sSA.Bounds(1).lLbound = 0
sSA.Bounds(1).cElements = sBMP.bmWidthBytes
sSA.pvData = sBMP.bmBits

CopyMemory ByVal VarPtrArray(sPic), VarPtr(sSA), 4

aSA.cbElements = 1
aSA.cDims = 2
aSA.Bounds(0).lLbound = 0
aSA.Bounds(0).cElements = aBMP.bmHeight
aSA.Bounds(1).lLbound = 0
aSA.Bounds(1).cElements = aBMP.bmWidthBytes
aSA.pvData = aBMP.bmBits

CopyMemory ByVal VarPtrArray(aPic), VarPtr(aSA), 4

For J = y To y + (nHeight - 1)
For I = x * 3 To (x + nWidth) * 3 Step 3
'I - x + xSrc, J - y + ySrc

nSrcX = ((I / 3) - x + xSrc) * 3
nSrcY = J - y + ySrc

AlphaVal = aPic(nSrcX + 2, nSrcY)
SrcVal = sPic(nSrcY + 2, nSrcY)
DestVal = dPic(I + 2, J)

TempR = (AlphaVal * CLng(SrcVal + 256 - DestVal)) / 256 + DestVal - AlphaVal

AlphaVal = aPic(nSrcX + 1, nSrcY)
SrcVal = sPic(nSrcY + 1, nSrcY)
DestVal = dPic(I + 1, J)

TempG = (AlphaVal * CLng(SrcVal + 256 - DestVal)) / 256 + DestVal - AlphaVal

AlphaVal = aPic(nSrcX, nSrcY)
SrcVal = sPic(nSrcY, nSrcY)
DestVal = dPic(I, J)

TempB = (AlphaVal * CLng(SrcVal + 256 - DestVal)) / 256 + DestVal - AlphaVal

dPic(I + 2, J) = TempR
dPic(I + 1, J) = TempG
dPic(I, J) = TempB

Next I
Next J

CopyMemory ByVal VarPtrArray(dPic), 0&, 4
CopyMemory ByVal VarPtrArray(sPic), 0&, 4
CopyMemory ByVal VarPtrArray(aPic), 0&, 4

End FunctionI know there's still lots to be done but it would be functional, for now. But it isn't: the arrays are empty (0, 0 is index out of bounds). Do you, or the MSDN, have anything to say to this?

Valkan
Nov 14th, 2002, 12:39 AM
Hum... ok, by reading your code i didn't see something wrong at first glance so i copied it (and btw... is there a way to copy correctly code posted on this board?) and try to use your function. And something very strange is happenig... after the getobject calls, every member for all the bitmap variable are set correctly... Every members exepted for the bmbits wich is always 0 so no pointer to the data!? Now, unless my computer is in worst shape than i tought and that does this only for me :rolleyes:, This would be why you get the out of bound error since copymemory will fail.

So now i'm speechless... i've seen exemple using this technique to change the pixels from a bitamp and even used it myselt with success. So why is it not working now... i really don't know (that's why i brought up the computer being in bad shape thing... i know i've already done this... but now it doesn't work!!! I just don't get it.)

so now i'm gonna go to sleep... i'll probably see things more clearly tomorow. If you get a chance, try to see what are the values for .bmbits when you run your code to see if you have the same problem.

Sastraxi
Nov 14th, 2002, 06:27 AM
Did I not mention that? D'oh. :) That's what problem I'm having, that the bmBits are 0, so that it doesn't work. I was thinking it had to do with the fact that the pictureboxes I'm getting the DCs from are autoredraw, but I'm not sure.

Valkan
Nov 14th, 2002, 09:03 AM
Originally posted by Sastraxi
Did I not mention that? D'oh. :) That's what problem I'm having, that the bmBits are 0, so that it doesn't work. I was thinking it had to do with the fact that the pictureboxes I'm getting the DCs from are autoredraw, but I'm not sure.
Well... if that is because of the autoredraw, I would be even more confuse... you see, i've tried almost any way I know of putting a darn bitmap in a dc (by using loadimage for the bitmap and then selecting it in a dc, in a memory dc, creating a bimap with createcompatiblebitmap. I've tried using picutre.image in getobject etc... ) but always to the same result, bmbits is set to 0 all the f'n (sorry it slipped :D ) time.

Man! this is suppose to work... I guess we will need help from others to for this one.

I have to go to work soon, but i'll try to work something again when i come back.

- Valkan

Valkan
Nov 14th, 2002, 09:10 AM
Just posted this problem in the API forum... perhaps someone will be able to help with the getobject problem. Because as i've said before, i'm pretty sure the rest of your code is good.

BTW, good luck with the alphablend, i've tried implementing it once... was pretty cool, but awfully slow with big pictures. If you manage to do it fast, please send me the code

- Valkan

Valkan
Nov 14th, 2002, 09:25 AM
I've found out to get the pointer to bits in the BITMAP variable set to something else than 0. if you use picturebox.picture in the getobject call, it will work. But i still don't know why it doesn't work with a bitmap object thought...

Valkan
Nov 14th, 2002, 09:37 AM
Well, i'm the one who talked about the msdn being a great source for api info... and I didn't even when to check to description for the getobject function. Here is what i've found out:
If hgdiobj is a handle to a bitmap created by calling CreateDIBSection, and the specified buffer is large enough, the GetObject function returns a DIBSECTION structure. In addition, the bmBits member of the BITMAP structure contained within the DIBSECTION will contain a pointer to the bitmap's bit values.

If hgdiobj is a handle to a bitmap created by any other means, GetObject returns only the width, height, and color format information of the bitmap. You can obtain the bitmap's bit values by calling the GetDIBits or GetBitmapBits function.


this would also clarify for me the diference between the .picture and .image of a picturebox... .picture seems to be a dib (since it works with getobject) and .image is a ddb.

- Valkan

Sastraxi
Nov 14th, 2002, 02:54 PM
Excellent, my friend. Excellent, excellent, excellent, excellent. I'm really glad you've helped me with all this!

PS. The Get/SetPixel only takes 0.003 seconds, on average, to do a 16x16 alphablend. It takes a bit longer for a 20x25 (0.01 s) but it's pretty sufficient for what I'm using it for. I just wanted to be able to do it just this bit faster, hehe ;)

Sastraxi
Nov 14th, 2002, 02:55 PM
I'm just about to try it, BTW. :D Just had to get out my enthusiasm, as it's been a long, boring, painful day of tests at school :/

Sastraxi
Nov 14th, 2002, 05:38 PM
We have a winner....

GetDIBits is awesome. This works completely, 100% now. Excellent, man, excellent!Public Function Morph2D(X As Long, Y As Long, NumRow As Long) As Long
Morph2D = (Y - 1) * NumRow + X
End Function
Public Function AlphaBltFast(ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal hAlphaDC As Long, ByVal xSrc As Long, ByVal ySrc As Long)
Dim I As Long
Dim J As Long

Dim TempR As Long
Dim TempG As Long
Dim TempB As Long

Dim AlphaVal As mRGB
Dim SrcVal As mRGB
Dim DestVal As mRGB

Dim dBitmap As Long
Dim dBMP As BITMAP
Dim dPic() As mRGB
Dim dMem As BITMAPINFO

Dim sBitmap As Long
Dim sBMP As BITMAP
Dim sPic() As mRGB
Dim sMem As BITMAPINFO

Dim aBitmap As Long
Dim aBMP As BITMAP
Dim aPic() As mRGB
Dim aMem As BITMAPINFO

dBitmap = GetCurrentObject(hDestDC, OBJ_BITMAP)
sBitmap = GetCurrentObject(hSrcDC, OBJ_BITMAP)
aBitmap = GetCurrentObject(hAlphaDC, OBJ_BITMAP)

GetObjectAPI dBitmap, Len(dBMP), dBMP
GetObjectAPI sBitmap, Len(sBMP), sBMP
GetObjectAPI aBitmap, Len(aBMP), aBMP

With dMem.bmiHeader
.biBitCount = 32
.biCompression = BI_RGB
.biPlanes = 1
.biSize = Len(dMem.bmiHeader)
.biWidth = dBMP.bmWidth
.biHeight = dBMP.bmHeight
ReDim Preserve dPic(0 To (.biWidth * .biHeight) - 1) As mRGB
End With

GetDIBits hDestDC, dBitmap, 0, dBMP.bmHeight, dPic(0), dMem, DIB_RGB_COLORS

With sMem.bmiHeader
.biBitCount = 32
.biCompression = BI_RGB
.biPlanes = 1
.biSize = Len(sMem.bmiHeader)
.biWidth = sBMP.bmWidth
.biHeight = sBMP.bmHeight
ReDim Preserve sPic(0 To (.biWidth * .biHeight) - 1) As mRGB
End With

GetDIBits hSrcDC, sBitmap, 0, sBMP.bmHeight, sPic(0), sMem, DIB_RGB_COLORS

With aMem.bmiHeader
.biBitCount = 32
.biCompression = BI_RGB
.biPlanes = 1
.biSize = Len(aMem.bmiHeader)
.biWidth = aBMP.bmWidth
.biHeight = aBMP.bmHeight
ReDim Preserve aPic(0 To (.biWidth * .biHeight) - 1) As mRGB
End With

GetDIBits hAlphaDC, aBitmap, 0, aBMP.bmHeight, aPic(0), aMem, DIB_RGB_COLORS

For J = Y To Y + (nHeight - 1)
For I = X To X + (nWidth - 1)

DestVal = dPic(Morph2D(I, dBMP.bmHeight - J, dBMP.bmWidth)) 'dColour.L = GetPixel(hDestDC, I, J)
SrcVal = sPic(Morph2D(I - X + xSrc, sBMP.bmHeight - (J - Y + ySrc), sBMP.bmWidth)) 'sColour.L = GetPixel(hSrcDC, I - x + xSrc, J - y + ySrc)
AlphaVal = aPic(Morph2D(I - X + xSrc, aBMP.bmHeight - (J - Y + ySrc), aBMP.bmWidth)) 'aColour.L = GetPixel(hAlphaDC, I - x + xSrc, J - y + ySrc)

AlphaVal.R = 255 - AlphaVal.R
AlphaVal.G = 255 - AlphaVal.G
AlphaVal.B = 255 - AlphaVal.B

TempR = (AlphaVal.R * CLng(SrcVal.R + 256 - DestVal.R)) / 256 + DestVal.R - AlphaVal.R
TempG = (AlphaVal.G * CLng(SrcVal.G + 256 - DestVal.G)) / 256 + DestVal.G - AlphaVal.G
TempB = (AlphaVal.B * CLng(SrcVal.B + 256 - DestVal.B)) / 256 + DestVal.B - AlphaVal.B

With dPic(Morph2D(I, dBMP.bmHeight - J, dBMP.bmWidth))
.R = TempR
.G = TempG
.B = TempB
End With

Next I
Next J

SetDIBits hDestDC, dBitmap, 0, dBMP.bmHeight, dPic(0), dMem, DIB_RGB_COLORS

End Function

Valkan
Nov 14th, 2002, 06:19 PM
Great man! I'm happy to see you have succeded. Beside it was a pleasure helping you... heck, it made me learn new stuff too :). stuff like the GDI can be a real pain in the ... sometime :( But hey, this was fun! Finally, I have a better understand of how to use the copy memory trick.:D

- Valkan

Sastraxi
Nov 15th, 2002, 05:06 PM
I think I have a complete understanding of it, you can get memory out in any format, which is both the beauty and the failing of it ;)

It's still pretty slow though.... but it's faster for larger images. I'm going to compile it to see how fast it goes.

[EDIT] Good news ;) Instead of 0.17s (IDE), it runs at 0.08s (compiled). More than two-times speed increase, which is nice.

dafhi
Nov 16th, 2002, 05:53 AM
Sastraxi, I would like to see your subs in action. I've been programming vb for about 4 years. I made my own very easy to use blit subs. I still don't know what an hDC is, and Bitblt looks like a heap of technical gibberish (I realize that it copies data extremely rapidly). Mostly it's the hDC and 7 other parameters that go with it that make it look more like "loose wires" than a "control panel". That's why I say I would like to see you post an example of your subs in action.

Sastraxi
Nov 16th, 2002, 10:23 AM
Do you mind running compiled code? The reason I'm hesitant to post the actual code is that I've used some pretty bad coding practices to get this test done...

If you don't trust me, I'll post it, but I hope you do :)

Sastraxi
Nov 16th, 2002, 10:33 AM
And here's a screenshot ;) Office, Apache, and EAC icons probably won't show up, I have their paths hard-coded. And if you don't have Winamp, it won't show up either. But IE should...

The Hobo
Nov 16th, 2002, 10:59 AM
Originally posted by Sastraxi
Do you mind running compiled code? The reason I'm hesitant to post the actual code is that I've used some pretty bad coding practices to get this test done...

If you don't trust me, I'll post it, but I hope you do :)

I got an error message: "failed to delete C:\" What does that mean? :p

That's pretty cool, though. What are you planning to do with it/use it for?

dafhi
Nov 16th, 2002, 11:15 AM
intresting.. at first click I got .11s, and second and later i was getting .06 and even .00 (1ghz duron). I got "subscript out of" after clicking about 20 times.

'Then don't click 20 times."

NoteMe
Nov 16th, 2002, 11:30 AM
Dafi: I got the same error message after clicking about 50 times.

The first result was 11, and after that it used 1,2,3 (Athlon 1,9+)...I have WinAmp, but it didn't show. But IE did).

cyborg
Nov 16th, 2002, 11:46 AM
took 0.02 for me..

i would like to have the code.....can you attach it please :)

Sastraxi
Nov 16th, 2002, 12:21 PM
Okay, but let me clean it up first. There's definately some stuff that's draining the memory like crazy, I'll do a test.

I've found the problem, which lies in the SmoothIconBlt function. I think it's the memory DCs I'm creating, let me check it and I'll post!

Sastraxi
Nov 16th, 2002, 12:22 PM
And I'll put in a little special effect for you guys, enumerating the real quicklaunch icons and sticking the first 5 in ;)

Sastraxi
Nov 16th, 2002, 12:35 PM
Okay, DON'T run this program anymore, lol. It has a huge memory leak that eventually destroys all of your memory... lol. Anyway, you might notice that the subscript out of range is in a horrible, Win16-emulation bold font. That shows real trouble, so, like I said, don't use it until I figure out what's wrong with it ;)

dafhi
Nov 16th, 2002, 02:30 PM
This was very tricky to find: in win98 that I use, when you double-click to start a file, a mouseup event occurs. It was causing an error in one of my projects.

Sastraxi
Nov 16th, 2002, 04:58 PM
Here's the code, tell me if you're able to fix the memory leaks...

cyborg
Nov 16th, 2002, 06:27 PM
thanks alot! that will be really useful for me! :)

Sastraxi
Nov 16th, 2002, 10:19 PM
Yeah, use it an any way you please :) I just hope you tell me about anything you use it in ;)

Sastraxi
Nov 16th, 2002, 10:50 PM
Okay, found out how to fix the Memory Leak in SmoothIconBlt.

New/Changed Code:Public Function DestroyDC(ByVal DC As Long, ByVal hOldBitmap As Long) As Long
DeleteObject SelectObject(DC, hOldBitmap)
ReleaseDC GetDesktopWindow, DC
DeleteDC DC
End Function

Public Function CreateMyDC(WidthInPixels As Long, HeightInPixels As Long, ByRef hOldBitmap As Long, Optional CompatibleDC As Long) As Long
'## NOTE THIS FUNCTION IS FROM SOMEONE ON VBW. I CAN'T REMEMBER THEIR NAME SO IF YOU DO, PLEASE
'## TELL ME SO APPROPRIATE THANKS CAN BE GIVEN

Dim hCompatibleDC As Long
Dim hMemDC As Long

'check there is a compatible DC
If CompatibleDC = 0 Then

hCompatibleDC = GetDC(GetDesktopWindow)

Else

hCompatibleDC = CompatibleDC

End If

'CreateDC
hMemDC = CreateCompatibleDC(hCompatibleDC)

'Get Default Bitmap Out of DC and Delete it and Put New one in.

hOldBitmap = SelectObject(hMemDC, CreateCompatibleBitmap(hCompatibleDC, WidthInPixels, HeightInPixels))

'and We're Done
CreateMyDC = hMemDC

End Function
Public Function SmoothIconBlt(ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal hExeSrc As String, ByVal hIndex As Long, ByVal hSmallIcon As Boolean, Optional SmoothValue As Long = smoothval) As Long
Dim hSmIco As Long
Dim hLgIco As Long
Dim hResult As Long

Dim hImgDC As Long
Dim hMaskDC As Long
Dim hTempDC As Long

Dim hImgOld As Long
Dim hMaskOld As Long
Dim hTempOld As Long

hImgDC = CreateMyDC(16, 16, hImgOld)
hMaskDC = CreateMyDC(16, 16, hMaskOld)
hTempDC = CreateMyDC(16, 16, hTempOld)

Call ExtractIconEx(hExeSrc, hIndex, hLgIco, hSmIco, 1)
If hSmallIcon Then
hResult = DrawIconEx(hMaskDC, 0, 0, hSmIco, 16, 16, 0, 0, DI_MASK)
hResult = DrawIconEx(hImgDC, 0, 0, hSmIco, 16, 16, 0, 0, DI_IMAGE)
SmoothMaskFast hTempDC, hMaskDC, 0, 0, 16, 16, SmoothValue
AlphaBltFast hDestDC, X, Y, 16, 16, hImgDC, hMaskDC, 0, 0
Else
hResult = DrawIconEx(hMaskDC, 0, 0, hLgIco, 32, 32, 0, 0, DI_MASK)
hResult = DrawIconEx(hImgDC, 0, 0, hLgIco, 32, 32, 0, 0, DI_IMAGE)
SmoothMaskFast hTempDC, hMaskDC, 0, 0, 32, 32, SmoothValue * 4
AlphaBltFast hDestDC, X, Y, 32, 32, hImgDC, hMaskDC, 0, 0
End If
DestroyIcon hSmIco: DestroyIcon hLgIco

DestroyDC hImgDC, hImgOld
DestroyDC hMaskDC, hMaskOld
DestroyDC hTempDC, hTempOld

End Function

cyborg
Nov 16th, 2002, 11:48 PM
there gotta be some leaks left, cuz my comp gets really slow after using that program for a while, and i've got the error "cant create autoredraw image" or whatever it says...

Sastraxi
Nov 17th, 2002, 12:25 AM
Index Out of Bounds for SmoothMaskFast, is that your error? Yeah, I'm working on it, it doesn't seem to be fixed [yet]. There is also a MASSIVE memory leak in the TextBlt function (which is called by the CropTextBlt function, so both of them have leaks). If you can fix these, it'd be great.

cyborg
Nov 17th, 2002, 02:49 AM
no, the error message i got was "cant create autoredraw image"...

sorry, but im not so goot at there stuff so im not sure that i can be to any help... :(

but if i find anything, i'll let you know!

Sastraxi
Nov 17th, 2002, 09:08 AM
What function did you get the error in?

cyborg
Nov 17th, 2002, 02:52 PM
hmmm....im not sure...but it only happend after i used the program for a long while....
i can tell you if i get the error again...

Sastraxi
Nov 17th, 2002, 02:54 PM
You definately will. Huge memory leaks goin' on there :D
Valkan and I are discussing it in one of the other threads, why don't you take a look (I've posted code that fixes a few of the leaks).

dafhi
Nov 17th, 2002, 03:44 PM
cy, i've been meaning to mention this, i like your animator. It is well thought out and has professional elements. From what I remember, it didn't go past 25 frames.

cyborg
Nov 17th, 2002, 03:53 PM
thanks really much! :)
my animator has i limit of 999 frames
im planing do rewrite the whole program and add more objects (not only lines)