0

只是为了好玩,我想从 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而在第一个代码中,它们没有被声明。谁能解释发生了什么?

4

3 回答 3

3

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

  1. Integer在许多 API 调用中使用。但在 VBAInteger中是有符号的 16 位类型。Integer您的语句中的所有用途都Declare应该是Long一个有符号的 32 位整数。
  2. 您正在向屏幕 DC 绘图。你不应该这样做。它将产生不可预测的结果。屏幕归系统所有,您不应在该 DC 上绘图。你需要找到另一种方法来做你想做的任何事情。
于 2013-01-11T12:23:02.893 回答
1

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

Option Explicit

在每个模块的顶部。

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

在第二个示例中,您设置screenX为一个变量,它可以容纳任何数据类型,但您明确设置screenY为整数,并且整数不是您正在执行的正确数据类型。

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

注意:小心变体,因为它们会引入奇怪的、难以发现的错误。整数显然不是正确的类型,但您应该弄清楚您需要什么数据类型并显式声明它。

于 2013-01-11T04:52:24.390 回答
1

尝试:

Dim screenX As Integer
Dim screenY As Integer

因为Dim screenX, screenY As Integer实际上相当于:

Dim screenX As Variant
Dim screenY As Integer
于 2013-01-11T04:10:33.237 回答