vb6使用win32api创建窗口的求助
我的打算是用win32api来创建窗口,不过不知道为什么,运行的时候不能成功注册窗口类。代码如下:
模块的代码
程序代码:
‘窗口操作 ‘■■■■■■■■■■■■■■■ Option Explicit ‘发送终止信息 Private Declare Sub PostQuitMessage Lib "user32" (ByVal nExitCode As Long) ‘调用窗口过程 Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, _ ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long ‘加载光标 Private Declare Function LoadCursor Lib "user32" Alias "LoadCursorA" (ByVal hInstance As Long, ByVal lpCursorName As eCursor) As Long ‘加载图标 Private Declare Function LoadIcon Lib "user32" Alias "LoadIconA" (ByVal hInstance As Long, ByVal lpIconName As eIcon) As Long ‘创建实色画刷 Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long ‘删除对象(画刷) Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long ‘注册窗口类 Private Declare Function RegisterClassEx Lib "user32" Alias "RegisterClassExA" (pcWndClassEx As WindowClassEx) As Integer ‘移动窗口 Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long ‘拷贝内存 Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef pDest As Any, ByRef pSrc As Any, ByVal mLength As Long) ‘创建窗口扩展 Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" ( _ ByVal dwExStyle As Long, ByVal lpClassName As String, _ ByVal lpWindowName As String, ByVal dwStyle As Long, _ ByVal x As Long, ByVal y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, _ ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long ‘销毁窗口 Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long ‘传递消息 Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWindow As Long, ByVal wMsg As eWindowMessage, Optional ByVal wParam As Long = 0, Optional lParam As Any = vbNull) As Long ‘hWindow:窗口句柄 ‘wMsg:消息类型。见eWindowMessage枚举 ‘wParam:用来存储小段信息,如,标志 ‘lParam:用于存储消息所需的对象 ‘获得API错误信息 Private Declare Function GetLastError Lib "kernel32" () As Long ‘■■■■■■■■■■■■■■■ Private lPrevWndProc As Long ‘之前的回调结果 ‘■■■■■■■■■■■■■■■ ‘ClassName窗口类的常量声明 Public Const ClassMenu As String = "#32768" ‘菜单 Public Const ClassDesktopWindow As String = "#32769" ‘桌面窗口 Public Const ClassDialog As String = "#32770" ‘对话框窗口 Public Const ClassTaskbarSwitcher As String = "#32771" ‘任务栏切换窗口 Public Const ClassIconOnTitleBar As String = "#32772" ‘标题栏的图标 Public Const ClassMessage As String = "Message" ‘消息框窗口 Public Const ClassDDEMLEvent As String = "DDEMLEvent" ‘动态数据交换管理库(DDEML)事件窗口 Public Const ClassComboListBox As String = "ComboLBox" ‘组合列表框 Public Const ClassListBox As String = "ListBox" ‘列表框 Public Const ClassTextBox As String = "Edit" ‘编辑框 Public Const ClassComboBox As String = "ComboBox" ‘组合框 Public Const ClassCommandButton As String = "Button" ‘按钮 Public Const ClassScrollBar As String = "ScrollBar" ‘滚动条 Public Const ClassStaticControl As String = "Static" ‘静态控件 Public Const ClassMDIClilent As String = "MDIClient" ‘MDI窗口 Public Const ClassIPv4AddressBar As String = "SysIPAddress32" ‘IPv4地址栏 Public Const ClassStatusBar As String = "msctls_statusbar32" ‘状态栏 Public Const ClassToolBar As String = "ToolbarWindow32" ‘工具栏 Public Const ClassListView As String = "SysListView32" ‘多列列表框 Public Const ClassTreeView As String = "SysTreeView32" ‘树状管理框 ‘■■■■■■■■■■■■■■■ Public Enum eDrawExtendStyle ‘扩展样式 eAcceptFiles = &H10 ‘eAcceptFiles:指定以该风格创建的窗口接受一个拖拽文件。 eAppWindow = &H40000 ‘eAppWindow:当窗口可见时,将一个顶层窗口放置到任务条上。 eClientEdge = &H200 ‘eClientEdge:指定窗口有一个带阴影的边界。 eComPositionited = &H2000000 ‘eComPositionited:指定复合窗口。 eContextHelp = &H400 ‘eContextHelp:在窗口的标题条包含一个问号标志。当用户点击了问号时,鼠标光标变为一个问号的指针。如果点击了一个子窗口,则子窗日接收到WM_Help消息。子窗口应该将这个消息传递给父窗口过程,父窗口再通过Help_WM_Help命令调用WinHelp函数。这个Help应用程序显示一个包含子窗口帮助信息的弹出式窗口。 eContextHelp不能与eMaxmizeBox和eMinimizeBox同时使用。 eControlParent = &H10000 ‘eControlParent:允许用户使用Tab键在窗口的子窗口间搜索。 eDefault = &H0 ‘eDefault:缺省设置(不使用额外样式)。 eDialogModalFrame = &H1 ‘eDialogModalFrame:创建一个带双边的窗口:该窗口可以在dwStyle中指定eCaption风格来创建一个标题栏。 eLayered = &H80000 ‘eLayered:指定窗口是分层的。 eLayoutRightToLeft = &H400000 ‘eLayoutRightToLeft:创建一个水平原点位于右边缘的窗口。水平值增加到左侧。 eLeft = &H0 ‘eLeft:窗口具有左对齐属性,这是缺省设置的。 eLeftScrollBar = &H4000 ‘eLeftScrollBar:如果外壳语言是如Hebrew,Arabic,或其他支持reading order alignment的语言,则标题条(如果存在)则在客户区的左部分。若是其他语言,在该风格被忽略并且不作为错误处理。 eLeftToRightReading = &H0 ‘eLeftToRightReading:窗口文本以LEFT到RIGHT(自左向右)属性的顺序显示。这是缺省设置的。 eMDIChild = &H40 ‘eMDIChild:创建一个MDI子窗口。 eNoActivate = &H8000000 ‘eNoActivate:创建一个未被激活的窗口。 eNoInheritLayout = &H100000 ‘eNoInheritLayout:创建一个无法继承的布局窗口。 eNoParentNotify = &H4 ‘eNoParentNotify:指明以这个风格创建的窗口在被创建和销毁时不向父窗口发送WM_PARENTNOTFY消息。 eNoRedirectionBitmap = &H200000 ‘eNoRedirectionBitmap:指定窗口没有重定向的位图。 eRight = &H1000 ‘eRight:窗口具有普通的右对齐属性,这依赖于窗口类。只有在外壳语言是如Hebrew,Arabic或其他支持读顺序对齐(reading order alignment)的语言时该风格才有效,否则,忽略该标志并且不作为错误处理。 eRightScrollBar = &H0 ‘eRightScrollBar:垂直滚动条在窗口的右边界。这是缺省设置的。 eRightToLeftReading = &H2000 ‘eRightToLeftReading:如果外壳语言是如Hebrew,Arabic,或其他支持读顺序对齐(reading order alignment)的语言,则窗口文本是一自左向右)RIGHT到LEFT顺序的读出顺序。若是其他语言,在该风格被忽略并且不作为错误处理。 eStaticEdge = &H20000 ‘eStaticEdge:为不接受用户输入的项创建一个三维边界风格 eToolWindow = &H80 ‘eToolWindow:创建工具窗口,即窗口是一个游动的工具条。工具窗口的标题条比一般窗口的标题条短,并且窗口标题以小字体显示。工具窗口不在任务栏里显示,当用户按下alt+Tab键时工具窗口不在对话框里显示。如果工具窗口有一个系统菜单,它的图标也不会显示在标题栏里,但是,可以通过点击鼠标右键或Alt+Space来显示菜单。 eTopMost = &H8 ‘eTopMost:指明以该风格创建的窗口应放置在所有非最高层窗口的上面并且停留在其L,即使窗口未被激活。使用函数SetWindowPosition来设置和移去这个风格。 eTransparent = &H20 ‘eTransparent:指定以这个风格创建的窗口在窗口下的同属窗口已重画时,该窗口才可以重画。由于其下的同属窗口已被重画,该窗口是透明的。 eWindowEdge = &H100 ‘eWindowEdge:指定窗口具有边框。 eWindowClientEdge = eWindowEdge Or eClientEdge ‘eWindowClientEdge:eClientEdge和eWindowEdge的组合。 ePaletteWindow = eWindowEdge Or eToolWindow Or eTopMost ‘ePaletteWindow:调色板窗口。eWindowEdge, eToolWindow和eWX_TOPMOST风格的组合 End Enum Public Enum eDrawStyle ‘基本样式 eBorder = &H800000 ‘eBorder:创建一个单边框的窗口。 eCaption = &HC00000 ‘eCaption:创建一个有标题框的窗口(包括eBorder风格)。 eChild = &H40000000 ‘eChild:创建一个子窗口。这个风格不能与ePopup风格合用。 eClipChildren = &H2000000 ‘eClipChildren:当在父窗口内绘图时,排除子窗口区域。在创建父窗口时使用这个风格。 eClipSiblings = &H4000000 ‘eClipSiblings:排除子窗口之间的相对区域,也就是,当一个特定的窗口接收到WM_PAINT消息时,eClipSiblings 风格将所有层叠窗口排除在绘图之外,只重绘指定的子窗口。如果未指定eClipSiblings风格,并且子窗口是层叠的,则在重绘子窗口的客户区时,就会重绘邻近的子窗口。 eDisabled = &H8000000 ‘eDisabled:创建一个初始状态为禁止的子窗口。一个禁止状态的窗日不能接受来自用户的输人信息。 eDialogFrame = &H400000 ‘eDialogFrame:创建一个带对话框边框风格的窗口。这种风格的窗口不能带标题条。 eGroUp = &H20000 ‘eGroUp:指定一组控制的第一个控制。这个控制组由第一个控制和随后定义的控制组成,自第二个控制开始每个控制,具有eGroUp风格,每个组的第一个控制带有eTabStop风格,从而使用户可以在组间移动。用户随后可以使用光标在组内的控制间改变键盘焦点。 eHorizontalScrollBar = &H100000 ‘eHorizontalScrollBar:创建一个有水平滚动条的窗口。 eMaxmize = &H1000000 ‘eMaxmize:创建一个具有最大化按钮的窗口。该风格不能与eContextHelp风格同时出现,同时必须指定eSystemtemMenu风格。 eMaxmizeBox = &H10000 ‘eMaxmizeBox:创建一个允许最大化的窗口。 eMinimize = &H20000000 ‘eMinimize:创建一个具有最小化按钮的窗口。该风格不能与eContextHelp风格同时出现,同时必须指定eSystemtemMenu风格。 eMinimizeBox = &H20000 ‘eMinimizeBox:创建一个允许最小化的窗口。 eOverLapped = &H0& ‘eOverLapped:产生一个层叠的窗口。一个层叠的窗口有一个标题条和一个边框。与eTiled风格相同。 ePopup = &H80000000 ‘ePopup:创建一个弹出式窗口。该风格不能与eChild风格同时使用。 eSystemtemMenu = &H80000 ‘eSystemtemMenu:创建一个在标题条上带有窗口菜单的窗口,必须同时设定eCaption风格。 eTabStop = &H10000 ‘eTabStop:创建一个控制,这个控制在用户按下Tab键时可以获得键盘焦点。按下Tab键后使键盘焦点转移到下一具有eTabStop风格的控制。 eThickFrame = &H40000 ‘eThickFrame:创建一个具有可调边框的窗口,与eSizeBox风格相同。 eVisible = &H10000000 ‘eVisible:创建一个初始状态为可见的窗口。 eVerticalScrollBar = &H200000 ‘eVerticalScrollBar:创建一个有垂直滚动条的窗口。 eChildWindow = eChild ‘eChildWindow:创建一个子窗口。与eChild风格相同。 eIconic = eMinimize ‘eIconic:创建一个初始状态为最小化状态的窗口。与eMinimize风格相同。 eOverLappedWindow = eOverLapped Or eCaption Or eSystemtemMenu Or eThickFrame Or eMinimizeBox Or eMaxmizeBox ‘eOverLappedWindow:创建一个具有eOverLapped,eCaption,eSystemtemMenu eThickFrame,eMinimizeBox,eMaxmizeBox风格的层叠窗口,与eTiledWindow风格相同。 ePopupWindow = ePopup Or eBorder Or eSystemtemMenu ‘ePOPUWindow:创建一个具有eBorder,ePopup,eSystemtemMenu风格的窗口,eCaption和ePopupWindow必须同时设定才能使窗口某单可见。 eSizeBox = eThickFrame ‘eSizeBox:创建一个可调边框的窗口,与eThickFrame风格相同。 eTiled = eOverLapped ‘eTiled:产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框。与eOverLapped风格相同。 eTiledWindow = eOverLappedWindow ‘eTiledWindow:创建一个具有eOverLapped,eCaption,eSystemtemMenu, MS_THICKFRAME, eMinimizeBox,eMaxmizeBox风格的层叠窗口。与eOverLappedWindow风格相同。 End Enum Public Enum eCursor ‘光标 eCursorArrow = 32512& ‘正常 eCursorBackground = 32650& ‘后台运行,鼠标旁边带沙漏 eCursorCross = 32515& ‘十字 eCursorHand = 32649& ‘手型 eCursorQuestion = 32651& ‘帮助选择,鼠标旁边带问号 eCursorEdit = 32513& ‘工(I)字,用于编辑 eCursorForbid = 32648& ‘禁止 eCursorSize = 32646& ‘调节大小,即四个方向的箭头 eCursorSizeDiagonal2 = 32643& ‘对角线2,即东北-西南方向↙↗ eCursorSizeDiagonal1 = 32642& ‘对角线1,即西北-东南方向↖↘ eCursorSizeNorthSouth = 32645& ‘竖直,即北-南方向 eCursorSizeEastWest = 32644& ‘水平,即东-西方向 eCursorSizeBusy = 32514& ‘忙碌,即沙漏 End Enum Public Enum eIcon ‘图标 eIconApplicatiion = 32512& ‘应用程序的图标 eIconAsterisk = 32516& ‘星号图标 eIconHandShape = 32513& ‘手型图标 eIconExclamation = 32515& ‘感叹号图标 eIconQuestion = 32514& ‘问号图标 eIconShield = 32518& ‘盾牌图标 eIconWinLogo = 32517& ‘Windows的logo End Enum Public Enum eWindowSize ‘窗口形状 eWindowSizeRestored = 0 ‘还原 eWindowSizeMinimized = 1 ‘最小化 eWindowSizeMaxinized = 2 ‘最大化 eWindowSizeShow = 3 ‘显示 eWindowSizeHide = 4 ‘隐藏 End Enum Public Enum eClassStyle ‘窗口类样式 eClassStyleVerticalRedraw = &H1& ‘如果窗口的位置或高度发生改变,将重绘窗口 eClassStyleHorizontalRedraw = &H2& ‘如果窗口的位置或宽度发生改变,将重绘窗口 eClassStyleDoubleClicks = &H8& ‘当用户双击窗口时,将向窗口函数发送鼠标双击消息 eClassStyleOwnDeviceContext = &H20& ‘为同一个窗口类中的每个窗口创建一个唯一的设备上下文 eClassStyleClassDeviceContext = &H40& ‘分配一个设备环境并被类中的所有窗体共享。它是可以适用于一个应用程序的若干线程创建的一个相同类的窗体。当多个线程试图同时使用相同的设备环境时,系统只允许一个线程成功地进行绘图操作 eClassStyleParentDeviceContext = &H80& ‘设置子窗口中剪下的矩形区域到父窗口中,以使子窗口可以在父窗口上绘图。指定该风格可以提高应用程序的性能 eClassStyleNoCloseButton = &H200& ‘窗口中的“关闭”按钮不可见 eClassStyleSaveBits = &H800& ‘把被窗口遮掩的屏幕图像作为位图保存起来。当该窗口被移动时,Windows操作系统使用被保存的位图来重建屏幕图像 eClassStyleByteAlignClient = &H1000& ‘窗口的客户区域以“字符边界”对齐,当系统调整窗口的水平位置时,客户区域的左边坐标是8的整数倍 eClassStyleByteAlignWindow = &H2000& ‘窗口以“字符边界”对齐,当系统调整窗口的水平位置时,客户区域的左边坐标是8的整数倍 eClassStyleGlobalClass = &H4000& ‘指定此窗体类是一个应用程序全局类。应用程序全局类是由一个在进程中对所有模块有效的exe或dll注册的窗体类 eClassStyleIME = &H10000 ‘输入法(尚不明确) eClassStyleDropShadow = &H20000 ‘窗体投影(尚不明确) eClassStyleResizeRedraw = eClassStyleVerticalRedraw Or eClassStyleHorizontalRedraw ‘如果窗口的位置或大小发生改变,将重绘窗口 End Enum Public Enum eWindowMessage ‘窗口消息 eWindowMessageCreate = &H1& ‘创建一个窗口 eWindowMessageDestory = &H2& ‘当一个窗口被破坏时发送 eWindowMessageMove = &H3& ‘移动一个窗口 eWindowMessageSize = &H5& ‘改变一个窗口的大小 eWindowMessageActivate = &H6& ‘一个窗口被激活或失去激活状态 eWindowMessageSetFocus = &H7& ‘一个窗口获得焦点 eWindowMessageLoseFocus = &H8& ‘一个窗口失去焦点 eWindowMessageEnable = &HA& ‘一个窗口改变成Enable状态 eWindowMessageSetRedraw = &HB& ‘设置窗口是否能重画 '以下部分内容省略 End Enum ‘■■■■■■■■■■■■■■■ Public Type WindowClassEx Size As Long ‘WindowClassEx的大小,以字节为单位。可用LenB获得 Style As eClassStyle ‘窗口样式,详见枚举eClassStyle lpWindowProcess As Long ‘回调函数的返回值。当鼠标键盘在该窗口上操作时,该窗口收到了这个消息。此时他的lpfnWndProc指向一个回调函数,该窗口将参数送到回调函数,由回调函数执行动作 ClassExtra As Long ‘指定紧跟在窗口类结构后的附加字节数,即给类额外预留的空间 WindowExtra As Long ‘指定紧跟在窗口类结构后的附加字节数,即给窗口额外预留的空间 hInstance As Long ‘该窗口的句柄 hIcon As Long ‘该窗口图标的句柄 hCursor As Long ‘该窗口光标的句柄 hBrushBackground As Long ‘背景画刷的句柄 MenuName As String ‘菜单名 ClassName As String ‘类名 hIconInTaskbar As Long ‘窗口在任务栏处显示的图标的句柄 End Type ‘■■■■■■■■■■■■■■■ Public Function NewWindow(ByVal Style As eDrawStyle, ByVal ExtendStyle As eDrawExtendStyle, ByVal ClassName As String, ByVal WindowTitle As String, ByVal Left As Long, ByVal Top As Long, ByVal Width As Long, ByVal Height As Long) As Long NewWindow = CreateWindowEx(ExtendStyle, ClassName, WindowTitle, Style, Left, Top, Width, Height, 0, 0, App.hInstance, vbNull) End Function Public Function NewControl(ByVal hParent As Long, ByVal Style As eDrawStyle, ByVal ExtendStyle As eDrawExtendStyle, ByVal ClassName As String, ByVal WindowTitle As String, ByVal Left As Long, ByVal Top As Long, ByVal Width As Long, ByVal Height As Long, Optional ByVal hMenu As Long = 0&) As Long NewControl = CreateWindowEx(ExtendStyle, ClassName, WindowTitle, Style Or eChild, Left, Top, Width, Height, hParent, hMenu, App.hInstance, vbNull) End Function Public Sub DelWindow(ByVal hWindow) DestroyWindow hWindow End Sub Public Sub DelControl(ByVal hControl) DestroyWindow hControl End Sub Private Function LWord(ByVal nInput As Long) As Long ‘取低位 LWord = nInput And &HFFFF End Function Private Function HWord(ByVal nInput As Long) As Long ‘取高位 Dim t As Long t = nInput And &HFFFF0000 CopyMemory HWord, t, LenB(t) / 2 End Function Public Function GetAddr(ByVal addr As Long) As Long ‘取得函数的地址 GetAddr = addr End Function Private Function WndProc(ByVal hwnd As Long, ByVal wMsg As eWindowMessage, Optional ByVal wParam As Long = 0, Optional ByVal lParam As Long = 0) As Long Select Case wMsg Case eWindowMessageDestory PostQuitMessage (0) Case eWindowMessageSize If wParam <> eWindowSize.eWindowSizeHide And wParam <> eWindowSize.eWindowSizeMinimized Then MoveWindow hwnd, 0, 0, LWord(lParam), HWord(lParam), -1 Case Else WndProc = CallWindowProc(lPrevWndProc, hwnd, wMsg, wParam, lParam) End Select WndProc = 0 End Function Public Function NewWindowEx(ByVal WindowTitle As String, _ ByVal Left As Long, ByVal Top As Long, _ ByVal Width As Long, ByVal Height As Long, _ Optional ByVal BackgroundColor As Long = 0, _ Optional ByVal BasicStyle As eDrawStyle = eOverLappedWindow, Optional ByVal ExtendedStyle As eDrawExtendStyle = eDefault, _ Optional ByVal Icon As eIcon = eIconApplicatiion, Optional ByVal Cursor As eCursor = eCursorArrow, _ Optional ByVal hMenu As Long = 0, Optional ByVal IconPath As String = "") As Long Dim nForm As WindowClassEx, Result As Integer On Error GoTo Err1 With nForm .Size = LenB(nForm) .Style = eClassStyleResizeRedraw .hBrushBackground = CreateSolidBrush(BackgroundColor) .hInstance = App.hInstance .hCursor = LoadCursor(0, Cursor) .hIcon = LoadIcon(0, Icon) .lpWindowProcess = GetAddr(AddressOf WndProc) .ClassName = "WinForm" .MenuName = "FormMenu" .hIconInTaskbar = .hIcon .ClassExtra = 0 .WindowExtra = 0 End With Result = RegisterClassEx(nForm) If Result <> 0 Then NewWindowEx = CreateWindowEx(ExtendedStyle, nForm.ClassName, WindowTitle, BasicStyle Or eVisible, Left, Top, Width, Height, 0, hMenu, App.hInstance, vbNull) Else Debug.Print "创建窗口失败:未能注册窗口类。" & vbCrLf & "错误代码:" & GetLastError() End If DeleteObject nForm.hBrushBackground Exit Function Err1: Debug.Print "创建窗口失败:属性错误。" If nForm.hBrushBackground <> 0 Then DeleteObject nForm.hBrushBackground End Function
调用的代码:
hForm = NewWindowEx("NewForm", Me.Left / Screen.TwipsPerPixelX, (Me.Top + Me.Height + 120) / Screen.TwipsPerPixelY, 300, 300, &HFF33CCFF, eOverLappedWindow, eDefault, eIconShield, eCursorArrow)
先谢谢各位大佬了