2 yangtianyu2004 yangtianyu2004 于 2016.01.16 11:48 提问

为什么MFC里可以引用的API函数,到VB.NET却不能用? 1C

为方便起见,许多情况下要用Winform来代替MFC,于是我选择了用VB语言编写程序。其中为了窗口的通信,要用到sendmessage函数。
图片说明

查阅了许多关于VB的资料(或许 VB6 与 VB.NET 的规则有点不同),编写代码如下。这个代码的目的很简单:就是要让Form1的button1被按下时候,关掉Form2。

要想达到这个目的,需要Form1对Form2发出WM_CLOSE消息。

使用工具是VS2010。

在一个project下面有三个代码:

这是发送WM__CLOSE信息的窗口:

 Imports System.Runtime.InteropServices

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Form2.Visible = True
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim kkk As Long
        kkk = SendMessage(Form2.Handle, WM_CLOSE, 0&, 0&) '关闭窗口的语句


        ' DestroyWindow(Form2.Handle) ’也是关闭窗口的语句,这里弃用
    End Sub
End Class


在VB里,所有API函数、所有常数,都需要用户声明。

 Module Module1
    Const SW_SHOWNORMAL = 1
    Const SW_SHOW = 5
    Const SW_SHOWMAXIMIZED = 3
    Const SW_SHOWDEFAULT = 10
    Public Const WM_CLOSE = &H10 '这是我所定义的常数
    Public Const WM_DESTROY = &H2
    Public Const WM_COPYDATA = &H4A
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal handle As Long, ByVal WM_WINDOW As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

'这是我所声明的API函数
    Public Declare Sub PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
    Public Declare Function DestroyWindow Lib "user32" Alias "DestroyWindow" (ByVal hwnd As Long) As Long
    Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
    Public Declare Function ShowWindowAsync Lib "user32" Alias "ShowWindowAsync" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long

End Module


这是接收WM__CLOSE 信息的窗口:

 Public Class Form2

End Class


DestroyWindow函数可以成功地关掉任何一个窗口。

而SendMessage函数却根本不起作用。为何窗口关不掉?是没发吗?

请出大侦探 spy++ 一查,发现无论参数是多少,目标窗口收到的永远都是WM_NULL (就是0)!

这说明,第一个参数(窗口句柄)对了,第二个参数(消息序号)错了。

这究竟是是Form1 发错了,还是 Form2 收错了?不得而知。

2个回答

91program
91program   Ds   Rxr 2016.01.16 12:32

改成 PostMessage 试试

yangtianyu2004
yangtianyu2004 原来还能收到个WM_NULL,改成postmessage之后什么也收不到了
2 年多之前 回复
yangtianyu2004
yangtianyu2004 改了,但是不起作用。
2 年多之前 回复
oyljerry
oyljerry   Ds   Rxr 2016.01.16 12:49

你的句柄正确的话,就是消息发送问题。比如post而不是send。消息窗口是否处理,过滤

yangtianyu2004
yangtianyu2004 改了,但是不起作用。这个处理过滤是怎么回事啊,为什么Destroywindow能正常使用?
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
VS2010中VB.NET中API函数的调用
API有两种调用方式: 第一种使用declare的API调用, Declare Function publicname Lib "libname" [Alias "alias"]      [([[ByVal] variable [As type]      [,[ByVal] variable [As type]]...])] As Type  其中 function表示有返回值,也可
vb.net中调用 Windows API
 vb.net中调用 Window API 的方法与 VB6中类似,也是必须使用Declare语句声明动态连接库(DLL)中外部程序的引用。下面做一个调用的实例, 调用 advapi32.dll中的 GetUserName 函数  来获得 系统登录的用户名 。Imports SystemImports System.TextImports Microsoft.VisualBasicPu
VB.NET调用Windows API函数 方法 (实例)
本例是Form中有一个按钮。 点击按钮,Form的Title会显示指定的文字。   Public Class Form3     Private Declare Auto Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal
VB.NET 调用Windows API 使用方法
整理:xiyangshanlu 来源:网络 关键字:Declare,Windows API,Declare Auto,Lib 与 Alias,DllImport   Windows API调用过去曾是Visual Basic编程中很重要的一部分,但在 Visual Basic .NET 几乎不必要了。只要有可能,应该使用 .NET Framework 中的托管代码而不是Windows AP
VB调用API函数
API函数快速入门--怎样在VB中声明和使用API函数--       一、在VB中声明API函数有两种方法:如果我们只在某个窗体中使用API函数,我们可以在窗体代码的 General部分声明它:     声明的语法是:   Private Declare Function ...   Private Declare Sub.....   这里必须采用Private声明
bitblt简易使用教程
BitBlt 是VB较常用的绘图API函数,绘图速度基本上是API中最快的了。它虽然使用简单,但功能强大,以下我就来给新手们简单的讲解一下它  的用法  BitBlt 的声明如下(在窗体代码中须在前面加上Private关键字):  Declare Func**** BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long
在vb.net中调用MATLAB函数
在网上搜到很多有关VS调用MATLAB函数的方法,以下是本人已经实现了的在vb.net中调用MATLAB函数的方法。         首先在MATLAB中配置环境:         1. mbuild -setup(mbuild后面有一个空格键),选择VS自带的编译器,而不是MATLAB带的。         2.点击MATLAB  file->new->deployment p
Vb.net声明API
Visual Basic .Net要实现查看文件中的图标,目前只使用.Net FrameWork SDK是无法实现这种功能的,正如前面所说,主要是由于.Net FrameWork SDK推出的时间较短,其功能还不可能面面俱到。解决问题的关键是正确使用Windows API函数,其中所涉及到的Windows API函数主要有二个:其一是获得指定文件中的图标数目;其二是从指定文件的指定位置导出图标的W
我做一键WIFI要用到的API
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。 Windows API 操作系统的用户接口 API函数包含在Windows系统目录下的动态连接库文件中。Windows API是一套用来控制Wi
C#中调用VB函数
在C#中调用Microsoft.VisualBasic命名空间下的类型验证函数http://www.1-100.org/AspNet/12682.htm 大家都知道VB.NET中有很多C#没有的函数,但这些函数却很好用:比如在C#中要重命名一个文件名,必须使用File.Move();方法,但如果文件很大的时候就比较麻烦了。而在VB.NET可以直接调用Rename(OldPath