Excel 2007 VBA win32 dll函数奇怪的行为?

时间:2013-01-11 04:00:04

标签: excel vba winapi dll gdi

为了好玩,我想从excel-vba调用一个GDI(win32)绘图函数。以下是我的dll函数声明。所有这些都是从win32导入的。

Public Declare Function GetDC _
Lib "user32.dll" _
(ByVal handle As Long) As Long

Public Declare Function MoveToEx _
Lib "gdi32.dll" _
(ByVal handle As Long, ByVal x As Integer, ByVal y As Integer, ByVal lppoint As Long) As Integer

Public Declare Function LineTo _
Lib "gdi32.dll" _
(ByVal handle As Long, ByVal x As Integer, ByVal y As Integer) As Integer

Public Declare Function ReleaseDC _
Lib "user32.dll" _
(ByVal hwnd As Long, ByVal hdc As Long) As Integer

Public Declare Function GetSystemMetrics _
Lib "user32.dll" _
(ByVal i As Integer) As Integer

我希望获得的结果是从屏幕左上角到右下角的一条线。以下代码给出了所需的结果。

Private Sub CommandButton1_Click()
    Dim dc As Long

    dc = GetDC(0)
    screenX = GetSystemMetrics(0)
    screenY = GetSystemMetrics(1)
    MoveToEx dc, 0, 0, 0
    LineTo dc, screenX, screenY

    ReleaseDC 0, dc
End Sub

但问题是以下代码没有做任何事情。为什么呢?

Private Sub CommandButton1_Click()
    Dim dc As Long
    Dim screenX, screenY As Integer

    dc = GetDC(0)
    screenX = GetSystemMetrics(0)
    screenY = GetSystemMetrics(1)
    MoveToEx dc, 0, 0, 0
    LineTo dc, screenX, screenY

    ReleaseDC 0, dc
End Sub

唯一的区别在于第二个代码,第三行声明了变量screenXscreenY,在第一个代码中,它们未被声明。有人可以解释一下发生了什么吗?

3 个答案:

答案 0 :(得分:3)

除了变量的所有错误声明,导致变量的无意使用,我还可以看到更多问题:

  1. 您在许多API调用中使用Integer。但在VBA中,Integer是一个带符号的16位类型。 Integer语句中Declare的所有用法应改为Long,带符号的32位整数。
  2. 您正在绘制屏幕DC。你不应该这样做。它将具有不可预测的结果。屏幕由系统拥有,您不应该使用该DC。你需要找到另一种方法去做你想做的事情。

答案 1 :(得分:1)

尝试:

Dim screenX As Integer
Dim screenY As Integer

因为Dim screenX, screenY As Integer实际上等同于:

Dim screenX As Variant
Dim screenY As Integer

答案 2 :(得分:1)

您不能将变量声明设置为必需。如果你这样做,你会看到

Option Explicit

位于每个模块的顶部。

由于您没有,screenXscreenY默认为第一个代码示例中的变体。

在第二个示例中,您将screenX设置为变量,它适用于任何数据类型,但您明确将screenY设置为整数,并且整数不是正确的数据输入您正在做的事情。

编辑:根据大卫的回答,你需要多头而不是整数。

注意:要小心变体,因为它们可能会引入奇怪的,难以发现的错误。一个整数显然不是正确的类型,但你应该找出你需要的数据类型并明确声明它。