-
Jun 27th, 2022, 02:03 PM
#1
CreateCompatibleDC
I don't understand how to reconcile this. Here's a quote from MSDN on the CreateCompatibleDC page:
When the memory DC is created, its display surface is exactly one monochrome pixel wide and one monochrome pixel high. Before an application can use a memory DC for drawing operations, it must select a bitmap of the correct width and height into the DC.
However, if I execute some code like the following...
Code:
Dim hMemDC As Long
hMemDC = CreateCompatibleDC(0&)
...and then do the following...
Code:
Debug.Print vbTab; "HORZ & VERT RES: "; GetDeviceCaps(hMemDC, HORZRES), GetDeviceCaps(hMemDC, VERTRES)
Debug.Print vbTab; "HORZ & VERT DESKTOP RES: "; GetDeviceCaps(hMemDC, DESKTOPHORZRES), GetDeviceCaps(hMemDC, DESKTOPVERTRES)
...I get the size of my primary monitor. Why aren't I just getting 1x1?
Also, none of those HORZRES, VERTRES, DESKTOPHORZRES, or DESKTOPVERTRES ever change, even when selecting bitmaps or DIBs into the DC. Can anyone explain what I'm missing here?
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 27th, 2022, 02:21 PM
#2
Re: CreateCompatibleDC
Originally Posted by Elroy
I don't understand how to reconcile this. Here's a quote from MSDN on the CreateCompatibleDC page:
However, if I execute some code like the following...
Code:
Dim hMemDC As Long
hMemDC = CreateCompatibleDC(0&)
...and then do the following...
Code:
Debug.Print vbTab; "HORZ & VERT RES: "; GetDeviceCaps(hMemDC, HORZRES), GetDeviceCaps(hMemDC, VERTRES)
Debug.Print vbTab; "HORZ & VERT DESKTOP RES: "; GetDeviceCaps(hMemDC, DESKTOPHORZRES), GetDeviceCaps(hMemDC, DESKTOPVERTRES)
...I get the size of my primary monitor. Why aren't I just getting 1x1?
Also, none of those HORZRES, VERTRES, DESKTOPHORZRES, or DESKTOPVERTRES ever change, even when selecting bitmaps or DIBs into the DC. Can anyone explain what I'm missing here?
https://docs.microsoft.com/en-us/win...-getdevicecaps
They are documented as returning the size of the physical screen. You could possible use GetClientRect assuming the DC is associated with a window. Not sure what to do if that isn't the case though.
-
Jun 27th, 2022, 03:13 PM
#3
Re: CreateCompatibleDC
You are asking about the device that the DC is compatible with. Try the same thing for a memory DC created compatible with a printer DC, that's the most common alternative.
-
Jun 27th, 2022, 03:15 PM
#4
Re: CreateCompatibleDC
Perhaps what you are after (?) can be obtained via:
Code:
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectW" ( _
ByVal hObject As Long, _
ByVal nCount As Long, _
ByRef Object As Any) As Long
Pass the bitmap handle and a BITMAP structure.
-
Jun 27th, 2022, 03:18 PM
#5
Re: CreateCompatibleDC
Oh yeah, you can use GetCurrentObject() to get the bitmap handle.
-
Jun 27th, 2022, 03:22 PM
#6
Re: CreateCompatibleDC
It might also be worth mentioning that the "wide" calls are quicker than ANSI calls. The latter go through an indirection process: taking any character values and transcoding them to wide, then making the wide call, then transcoding back.
It has been this way since at least NT 4.0, the shabby old ANSI calls are really there for Win9x compatibility where wide calls incur the same penalty in reverse.
-
Jun 27th, 2022, 03:24 PM
#7
Re: CreateCompatibleDC
u r not using CreateCompatibleDC alone
hDC = CreateCompatibleDC(0)
DIB = CreateDIBSection(hDC, DIBHeader...
the hDC is a clone of "0" that is the desktop hDC, so using GetDeviceCaps will point to the desktop.
CreateCompatibleDC is just making the hDC ready to be used for something.
like a picturebox 1x1 pixel, after that we need to size it, the background/forecolor etc.
so maybe the reason they have 1x1 is something about memory. not sure whats going on behind the scene, but could be pointers or a needed memory space, an expert maybe knows?
-
Jun 27th, 2022, 03:28 PM
#8
Re: CreateCompatibleDC
I'm pretty sure that the default bitmap is just another of the many GDI "stock objects" that costs nothing to create at runtime. There has to be something by default, so they use that one.
-
Jun 27th, 2022, 03:36 PM
#9
Re: CreateCompatibleDC
Originally Posted by dilettante
You are asking about the device that the DC is compatible with.
I think that's what I need to get my head around. I'll explore your suggestion of querying about a BITMAP. In fact, I've already done that and it returns what I expect.
I'm just still struggling why I need these DCs to get certain things done. I'll keep staring at it and reading MSDN and other resources.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 27th, 2022, 03:39 PM
#10
Re: CreateCompatibleDC
Originally Posted by Elroy
...I get the size of my primary monitor. Why aren't I just getting 1x1?
Also, none of those HORZRES, VERTRES, DESKTOPHORZRES, or DESKTOPVERTRES ever change, even when selecting bitmaps or DIBs into the DC. Can anyone explain what I'm missing here?
One of the things you will slowly realize about device contexts in GDI is that they are more about the objects selected into them than they are about the DC itself. The documentation will never tell you this directly so you're going to have to come to the realization on your own.
Anyways, if you want to measure the actual surface of a DC, you have to measure the hBitmap selected into it. Here is some ancient code I wrote 13 years ago that can measure an hBitmap:-
Code:
Public Function GetBmpWid(ByVal hBitmap As Long) As Long
Dim BmpInfo As BitmapInfo
Dim C As Long
Dim ScrDC As Long
ScrDC = GetDC(0)
BmpInfo.bmiHeader.biSize = 40
C = GetDIBits(ScrDC, hBitmap, 0, 0, 0, BmpInfo, DIB_RGB_COLORS)
GetBmpWid = BmpInfo.bmiHeader.biWidth
ReleaseDC 0, ScrDC
End Function
Public Function GetBmpHei(ByVal hBitmap As Long) As Long
Dim BmpInfo As BitmapInfo
Dim C As Long
Dim ScrDC As Long
ScrDC = GetDC(0)
BmpInfo.bmiHeader.biSize = 40
C = GetDIBits(ScrDC, hBitmap, 0, 0, 0, BmpInfo, DIB_RGB_COLORS)
GetBmpHei = BmpInfo.bmiHeader.biHeight
ReleaseDC 0, ScrDC
End Function
Of course that code won't work as is. It requires a few imports and definitions like BitmapInfo and GetDC but this kind of thing you end up having to write yourself when dealing with GDI.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|