C++ 在VBA中使用CreateDialog尝试创建无模式对话框

C++ 在VBA中使用CreateDialog尝试创建无模式对话框,c++,vba,api,dialog,modeless,C++,Vba,Api,Dialog,Modeless,我想在VBA 7.0中创建一个无模式弹出对话框。 到目前为止,最有希望的途径似乎是 首先,我尝试了CreateDialogW,收到了在DLL中找不到CreateDialogW的入口点 打开DLL后,我验证了该函数未列出。上面链接的MSDN参考将User32显示为此函数的DLL,并列出函数名CreateDialogW和CreateDialogA(分别为Unicode/ansi),但它们未在我的计算机上的此DLL中列出(Win 7 professional,64位) 因此,查看DLL中的函数列表,我

我想在VBA 7.0中创建一个无模式弹出对话框。 到目前为止,最有希望的途径似乎是

首先,我尝试了
CreateDialogW
,收到了在DLL中找不到CreateDialogW的
入口点
打开DLL后,我验证了该函数未列出。上面链接的MSDN参考将User32显示为此函数的DLL,并列出函数名
CreateDialogW
CreateDialogA
(分别为Unicode/ansi),但它们未在我的计算机上的此DLL中列出(Win 7 professional,64位)

因此,查看DLL中的函数列表,我看到了(每个函数的Ansi和Unicode版本)

我一直在尝试遵循MSDN并将C示例转换为VB,但我在某些地方遗漏了一些东西,我有点被卡住了,因为我不知道我做错了什么。代码编译和运行时没有错误,但在API调用时什么也没有发生——它执行了,但什么也没有发生

如果有人能给我指出正确的方向,我将不胜感激。 我目前的工作环境糟透了,我真的想把这个项目关起来

选项显式
'此处的C到VB类型声明的引用转换
'http://msdn.microsoft.com/en-us/library/aa261773(v=vs.60).aspx
'声明函数以赢得API CreateDialog函数
'http://msdn.microsoft.com/en-us/library/ms645434(v=vs.85).aspx
私有声明PtrSafe函数CreateDialog Lib“User32.dll”别名“CreateDialogParamW”_
(ByVal lpTemplateName作为LongPtr_
ByRef lpDialogFunc作为DIALOGPROC_
拜瓦尔·德维特帕姆,只要_
可选ByVal hInstance,只要_
可选ByVal hWndParent(长度相同)_
只要
'Windows样式常量
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx
公共建筑的边界长度=&H800000
Public Const WS_标题长度=&HC00000
公共常数w_CHILD的长度=&H40000000
Public Const WS_CHILDWINDOW的长度=&H40000000
Public Const WS_CLIPCHILDREN As Long=&H2000000
公共建筑的总长度=&H4000000
公共Const WS_已禁用,只要=&H8000000
公共常数WS_DLGFRAME As Long=&H400000
公共Const WS_组的长度=&H20000
公共建筑的长度=&H100000
公共常数WS_图标长度=&H20000000
公共常数WS_最大化长度=&H1000000
公共常数最大化盒子长度=&H10000
Public Const WS_最小化为Long=&H20000000
公共Const WS_MINIMIZEBOX As Long=&H20000
公共常量WS_重叠,长度=&H0
Public Const WS_弹出窗口长度=&h8000000
公共常数w_SIZEBOX长度=&H40000
Public Const WS_SYSMENU长度=&H80000
公共常数w_TABSTOP,长度=&H10000
Public Const WS_THICKFRAME As Long=&H40000
公共常数的平铺长度=&H0
公共常量WS_可见,长度=&h1000000
公用工程施工总工期=&H200000
Public Const WS_OVERLAPPED window As Long=(WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_THICKFRAME+WS_MINIMIZEBOX+WS_MAXIMIZEBOX)
公共常量WS_平铺窗口长度=(WS_重叠+WS_标题+WS_系统菜单+WS_THICKFRAME+WS_最小化框+WS_最大化框)
Public Const WS_POPUPWINDOW As Long=(WS_POPUP+WS_BORDER+WS_SYSMENU)
'为lpDialogFunc参数声明自定义类型
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms645469(v=vs.85).aspx
公共类型DIALOGPROC
hwndDlg尽可能长
uMsg As LongPtr
wparam尽可能长
lpram尽可能长
端型
'MAKEINTRESOURCE宏仿真
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms648029(v=vs.85).aspx
'按位函数示例如下所示:http://support.microsoft.com/kb/112651
'在此处找到VB转换:https://groups.google.com/forum/#!topic/microsoft.public.vb.winapi/UaK3S-bJaiQ_
修改为强类型并使用VB7的字符串指针
私有函数MAKEINTRESOURCE(ByVal lID作为LongPtr)作为LongPtr
MAKEINTRESOURCE=strprtr(“#”)和CStr(MAKELONG(lID,0)))
端函数
私有函数MAKELONG(ByRef wLow As Long,ByRef wHi As Long)
'声明变量
昏暗的LoLO,长得一样
暗淡无光
Dim LoHI尽可能长
昏昏欲睡
'从长整数值中获取高阶和低阶单词
GethilowordWlow,LoLO,HiLO
格希洛沃德,你好,你好
如果(wHi和&H8000&),则
MAKELONG=((wHi和&H7FFF&)65536)或(wLow和&HFFFF&)或&h8000000
其他的
MAKELONG=LoLO或(&H10000*LoHI)
'MAKELONG=((wHi*65535)+wLow)
如果结束
端函数
私有函数GetHiLoWord(lparam为Long,LOWORD为Long,HIWORD为Long)
'这是LPRAM的LOWORD:
LOWORD=LPRAM和&HFFFF&
“LOWORD现在等于65535或&HFFFF
'这是LPRAM的HIWORD:
HIWORD=lparam\&H10000和&HFFFF&
“HIWORD现在等于30583或&H7777
GetHiLoWord=1
端函数
公共功能TstDialog()
Dim dpDialog作为DIALOGPROC
dpDialog.hwndDlg=0
dpDialog.uMsg=StrPtr(“测试”)
dpDialog.lparam=0
dpDialog.wparam=0
CreateDialog hInstance:=0,lpTemplateName:=MAKEINTRESOURCE(WS_POPUPWINDOW+WS_VISIBLE),lpDialogFunc:=dpDialog,dwInitParam:=&H110
端函数

您在这个项目上的起步很差。您完全扰乱了的参数顺序,请注意
hInstance
参数是第一个,而
dwInitParam
参数是最后一个

您完全弄错了DIALOGPROC声明,它是一个函数指针。这需要在声明中输入
LongPtr
,并在您拨打电话时输入
AddressOf
接线员

这只是第一次1%的工作。下一个问题是t
Private Type DLGTEMPLATE
    style As Long
    dwExtendedStyle As Long
    cdit As Integer
    x As Integer
    y As Integer
    cx As Integer
    cy As Integer
End Type

Private Type DLGITEMTEMPLATE
    style As Long
    dwExtendedStyle As Long
    x As Integer
    y As Integer
    cx As Integer
    cy As Integer
    id As Integer
End Type

Private Type DLG
    dlgtemp As dlgtemplate
    menu As Long
    classname As String
    title As String
End Type

Private Declare PtrSafe Function CreateDialogIndirectParam Lib "User32.dll" Alias "CreateDialogIndirectParamW" _
  (ByVal hInstance As Long, _
  ByRef lpTemplate As DLGTEMPLATE, _
  ByVal hWndParent As Long, _
  ByVal lpDialogFunc As LongPtr, _
  ByVal lParamInit As Long) _
  As LongPtr

Const WM_INITDIALOG As Long = &H110
Const DS_CENTER As Long = &H800&
Const DS_SETFONT As Long = &H40
Const DS_MODALFRAME As Long = &H80
Const WS_EX_APPWINDOW As Long = &H40000
Dim d As DLG
d.dlgtemp.style = DS_MODALFRAME + WS_POPUP + WS_VISIBLE + WS_CAPTION + WS_SYSMENU
d.dlgtemp.dwExtendedStyle = WS_EX_APPWINDOW
d.dlgtemp.cdit = 0
d.dlgtemp.x = 100
d.dlgtemp.y = 100
d.dlgtemp.cx = 200
d.dlgtemp.cy = 200
d.menu = 0
d.title = "Test"
d.classname = "Test"

CreateDialogIndirectParam 0, d.dlgtemp, 0, AddressOf DlgFunc, 0
Public Function DlgFunc(ByVal hwndDlg As LongPtr, ByVal uMsg As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
    If uMsg = h110 Then  ' = WM_INITDIALOG - you should make a const for the various window messages you'll need...
        DlgFunc = True
    Else
        DlgFunc = False
    End If
End Function
Option Explicit

Private pUserForm As VBIDE.VBComponent

Private Sub Class_Initialize()
    ' Add the userform when created '
    Set pUserForm = ThisWorkbook.VBProject.VBComponents.Add(VBIDE.vbext_ct_MSForm)
End Sub
Private Sub Class_Terminate()
    ' remove the userform when instance is deleted '
    ThisWorkbook.VBProject.VBComponenets.Remove pUserForm
End Sub
Public Property Get UserForm() As VBIDE.VBComponent
    ' allow crude access to modify the userform '
    ' ideally this will be replaced with more useful methods '
    Set UserForm = pUserForm
End Property
Public Sub Show(ByVal mode As Integer)
    VBA.UserForms.Add(pUserForm.Name).Show mode
End Sub
Private Sub TestModelessLocal()

    Dim localDialog As New Dialog
    localDialog.UserForm.Properties("Caption") = "Hello World"
    localDialog.Show vbModeless

End Sub
Dim globalDialog As Dialog
Private Sub TestModeless()

    Set globalDialog = New Dialog
    globalDialog.UserForm.Properties("Caption") = "Hello World"
    globalDialog.Show vbModeless
    'Set globalDialog = Nothing  closes window and removes the userform '
    'Set gloablDialog = new Dialog should delete userform1 after added userform2'
End Sub
Option Explicit

Private frm As UserForm1

Sub test2()
    Set frm = New UserForm1
    frm.Show vbModeless
End Sub