如何使用SetWindowText及其句柄在VBA中设置窗口的标题



我在Windows 10上使用32位Excel 365中的VBA。

假设我在hWndApp中有一个记事本窗口的句柄,为什么下面没有设置窗口的标题?相反,它似乎什么也没做。

Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" _
(ByVal hwnd As Long, ByVal _
lpString As String) As Long
Call SetWindowText(hWndApp, "The handle to notepad is " & CStr(hWndApp))

作为已接受答案的后期添加,条件编译的示例同时满足MS Office 2010+(关键字VBA7(和其他/旧版本(例如Office 2007(的要求。

VBA7下的API函数正式要求LongPtr类型用于指向→手柄或→内存位置(注意特殊的PtrSafe前缀!(。

因此,窗口句柄在Office 2010或更高版本中被声明为LongPtr,在以前的版本中被宣布为Long;因此有必要通过条件编译常数(#If VBA7 Then.#End If(来区分不同的版本-注意:结合这些可能性可能还需要在用户过程中进行差异化变量声明(参见testChangeNotepadTitle(

提示:LongPtr不是真正的数据类型,因为它会根据实际32/64位环境转换为正确的数据类型。

请注意,64位系统可以安装为32位办公室或64位办公室。LongPtr支持编写可在32位和64位环境中运行的可移植代码。

旁注:在某些特殊情况下,除了VBA7之外,很少需要#If Win64指令(例如,在32位和64位系统上加载两个不同的dll或使用具有不同签名的函数(。

API函数

Option Explicit         ' declaration head of code module
#If VBA7 Then           ' MS Office 2010+
Private Declare PtrSafe Function FindWindow Lib "user32" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" ( _
ByVal hwnd As LongPtr, _
ByVal lpString As String) As Long
#Else
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" ( _
ByVal hwnd As Long, _
ByVal lpString As String) As Long
#End If

调用过程testChangeNotepadTitle

Sub testChangeNotepadTitle()
Const NotePadTitle As String = "Untitled - Notepad"   ' EN-US
'Const NotePadTitle As String = "Unbenannt - Editor"   ' DE
#If VBA7 Then
Dim hwndapp As LongPtr
#Else
Dim hwndapp As Long
#End If
hwndapp = FindWindow(vbNullString, NotePadTitle): Debug.Print hwndapp
SetWindowText hwndapp, "The handle to notepad is " & CStr(hwndapp)
End Sub

旁注窗口标题"无标题-记事本遵循区域设置;因此我添加了例如德国/奥地利(DE(的示例,标题为">";Unbenannt-编辑器-作为未推荐的过程常数。

关闭所有Notepad会话,打开新的空Notepad窗口并运行下一个代码。如果存在任何隐藏的此类过程,请检查任务管理器并将其杀死(如果有的话(:

Sub testChangeNotepadTitle()
Dim hWndApp As Long
hWndApp = FindWindow(vbNullString, "Untitled - Notepad"): Debug.Print hWndApp
SetWindowText hWndApp, "The handle to notepad is " & CStr(hWndApp)
End Sub

它不起作用吗?如果它有效,这只意味着你使用的窗口句柄是错误的。。。

你可能打开了更多的记事本窗口,API找到了第一个,而不是你认为的那个…

最新更新