Results 1 to 10 of 10

Thread: CreateCompatibleDC

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,942

    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.

  2. #2
    PowerPoster PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Pontypool, Wales
    Posts
    2,474

    Re: CreateCompatibleDC

    Quote Originally Posted by Elroy View Post
    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.

  3. #3
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    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.

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    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.

  5. #5
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: CreateCompatibleDC

    Oh yeah, you can use GetCurrentObject() to get the bitmap handle.

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    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.

  7. #7
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,731

    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?

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    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.

  9. #9

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,942

    Re: CreateCompatibleDC

    Quote Originally Posted by dilettante View Post
    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.

  10. #10
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,601

    Re: CreateCompatibleDC

    Quote Originally Posted by Elroy View Post
    ...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.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width