请问已知句柄如何获取可绘图的DC哦?或者这么说吧:窗体上一个 Picture1 控件,使用API:GetDC(Picture1.hwnd) 获得的DC与Picture1.hDC是不同的。。我是想问,假设只知道Picture1.hwnd(只是假设,这里假设不存在Picture1.hDC这个属性)
那么怎么通过API得到这个与Picture1.hDC一样的设备上下文呢??谢谢!

解决方案 »

  1.   

    这个简单啊,就用GetDC。比如:在文本框中显示图像。
    http://topic.csdn.net/u/20081027/12/871c9a0f-9f1d-4d54-8b00-4e890ac0496b.html
      

  2.   

    GetDC(Picture1.hwnd) 获得的DC与Picture1.hDC是一样的。测试一下:Option Explicit
    Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long, ByVal hdc As Long) As LongPrivate Sub Command1_Click()
            Dim pDC As Long
            pDC = GetDC(Picture1.hwnd)
            Debug.Print Picture1.hdc, pDC '结果一样都是-1224666264   -1224666264
            ReleaseDC Picture1.hwnd, pDC
    End Sub
      

  3.   

    Private Sub Form_Load()
    Dim dc1 As Long
    dc1 = GetDC(Picture1.hwnd)
    Debug.Print Picture1.hDC, dc1
    ReleaseDC Picture1.hwnd, dc1
    End Sub奇了怪了这段简单的代码,我在一个测试工程(就是新建工程之后立即双击窗口写这些)
    得到的结果与2楼结论一样,确实相同!而我在一个比较负责的窗体模块。里面有数个控件(编辑框/按钮/标签/选择框等等,还SET NEW了一个类模块对象。但这些都与DC无关啊,最多也是我在按了某按钮之后才会对屏幕执行GetDC(0)。)
    我同样是在Form_Load()过程里加上述代码,得到的结果却根本不同(没有一次相同)
     2080445464    100735897 
     419502903     1744896506 
    -1509879371   -318697057 
    -503243578     1593908121 
    -1442769840   -184478673 
    -1996415453    2030110907 前者为.HDC,后者为GetDC函数结果获得,对象就是Picture1。。这是为什么呢???
      

  4.   

    哈哈,明白了我终于知道是为什么了简单测试工程中的Picture1的AutoRedraw属性是False,而我那个复杂工程设置了AutoRedraw属性是True。。只要是True则一直就不相同,而False的话就一直相同。。问题是搞明白了。。可我想知道:这是为什么呢?(貌似是今年流行语^-^)
      

  5.   

    也许........与AutoReDraw有关.我的猜测:AutoReDraw为TRUE时,图片框会建立一个内存DC,所有绘的图会先在这内存DC里画上,然后再在适当的时候显示图象到屏幕DC,这才看见了.而AutoReDraw为FALSE时,只拥有一个屏幕DC.因此AutoReDraw为TRUE时,使用图片框属性得到的DC,与GETDC根据句柄得到的DC会不同.楼主自己试一下吧.
      

  6.   

    或许是这样吧。。可现在问题随之而来:AutoReDraw为FALSE后,我使用StretchDIBits绘制上去的图像就不显示了。。(当然没有把绘制操作写到Picture1_Paint过程中,因为有限制)所以请问,咋才能显示图像呢?是用啥API函数还是发送个什么消息??
      

  7.   

    refresh不好用哦我测试过,只有放到Picture1_Paint过程中会自动显示出来(这说明我绘制函数啥的没错误)但是我这个程序不希望在Picture1_Paint有代码,记得以前看什么资料的,有办法让控件强制刷新的。。可想不起来了郁闷。知道的帮帮我谢谢!!!
      

  8.   

    谁知道吗?简单点说就是不在_Paint过程的绘图如何显示啊???
      

  9.   

    是有这个问题。
    1、当PictureBox的AutoReDraw属性为FALSE时,只拥有一个屏幕DC,所以2楼的结果会一样。(缺省值FALSE)使对象的自动重绘无效,且将图形或文本只写到屏幕上。 当需要重画该对象时,Visual Basic 会激活对象绘制事件。
    2、当PictureBox的AutoReDraw属性为TRUE时,使 Form 对象或 PictureBox 控件的自动重绘有效。图形和文本输出到屏幕,并存储在内存的图象中,那就说明用GetDC(Picture1.hwnd)得到的DC会是内存DC,与Picture1.hDc不同。该对象不接受绘制事件,必要时,用存储在内存中的图象进行重绘。
      

  10.   


    看看MSDN的解释:AutoRedraw 属性
          返回或设置从图形方法到持久图形.的输出。语法object.AutoRedraw [= boolean]AutoRedraw 属性语法包含下面部分:部分 描述 
    object 对象表达式,其值是“应用于”列表中的一个对象。 
    Boolean 布尔表达式,指定如何重绘对象,“设置值”中有详细描述。 
    设置值boolean 的设置值如下:设置值 描述 
    True   使 Form 对象或 PictureBox 控件的自动重绘有效。图形和文本输出到屏幕,并存储在内存的图象中。该对象不接受绘制事件,必要时,用存储在内存中的图象进行重绘。 
    False (缺省值)使对象的自动重绘无效,且将图形或文本只写到屏幕上。 当需要重画该对象时,Visual Basic 会激活对象绘制事件。 
    说明使用下列图形方法工作,如:Circle、Cls、Line、Point、Print 和 Pset,该属性极为重要。利用这些方法,在改变对象大小或隐藏在另一个对象后又重新显示的情况下,设置 AutoRedraw 为 True,将在 Form 或 PictureBox 控件中自动重绘输出。 运行时 在程序中设置 AutoRedraw,可以在画持久图形(如背景色或网格)和临时图形之间切换。如果设置 AutoRedraw 为 False,以前的输出成为背景屏幕的一部分。当 AutoRedraw 设置为 False,用 Cls 方法清除绘图区时不会删除背景图形。把 AutoRedraw 改回 True 后,再用 Cls 将清除背景图形。注意 如果设置 BackColor 属性,所有图形和文本,包括持久图形,都被清除。一般来说,除非 AutoRedraw 设置为 True,所有图形都需用 Paint 事件显示。要取回在 AutoRedraw 设置为 True 时创建的持久图形,用 Image 属性。当 AutoRedraw 设置为 True 时,用对象的 hDC 属性可以将持久图形传送给Windows API。如果设置窗体的 AutoRedraw 属性为 False,然后最小化该窗体,则将 ScaleHeight 和 ScaleWidth 属性设置为图标大小。在 AutoRedraw 设置为 True 时,ScaleHeight 和 ScaleWidth 保持为恢复窗口的尺寸。如果设置 AutoRedraw 属性为 False,Print 方法将在诸如 Image 和 Shape 等图形控件的顶部打印。