SendMessage相关 如何告知消息的发送者消息已接收(在线等待)

Quady515 2003-03-11 04:53:20
如题,

因为消息是在线程中发的,如若告知消息的发送者消息已接收,线程会一直等下去
我试着用PostMessage,但因为附加消息中要发送的是字符串,故lParam传送的是地址,
接收者收到消息后按地址取值(CopyMemory),但取出的值并非就是发送的值,晕!
如果发送时lParam中放的是数值则收到的lParam就是发送的值。。。。。。

在线等待
...全文
274 29 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
Quady515 2003-03-14
  • 打赏
  • 举报
回复
在两个应用之间传递信息应该是发消息是最好的了,

再说了,我传递信息的地方是在一个应用的线程中.
Quady515 2003-03-14
  • 打赏
  • 举报
回复
问题并没有真正得到解决,
所以我放弃了题中方法,用其它办法解决了,
不会用到消息,也不用产生事件.

谢谢大家.
kensu 2003-03-13
  • 打赏
  • 举报
回复
干吗非得自己发送消息,定义好Event,然后用RaiseEvent通知调用者不就行了,
在API版就非的使用API吗?
Quady515 2003-03-12
  • 打赏
  • 举报
回复
UP
Quady515 2003-03-12
  • 打赏
  • 举报
回复
我试过用SendNotifyMessage替换上面代码中的PostMessage,

在线程中发送消息不能正确接收到lParam中的数据
然而发送消息不是在线程中时就能够正确收到数据
Quady515 2003-03-12
  • 打赏
  • 举报
回复
好像Pipe不能解决我的问题,

是这样的:
我需要定一个DLL,让其它程序调用,而这个DLL需要处理一些东东,比如装载一个很大的文本文件(1,000,000条记录)到数据库,其中每装载一定的记录数(10,000条记录)就需要告诉DLL的调用者装载的进度.又或者中途出了差错DLL必需告诉调用者出了错.如果仅一个线程我可以直接设置函数的返回值就行,但是这个DLL是多线程的,所以只能发消息才能告诉调用者当前线程发生了什么事,问题就出在这里.
differ1 2003-03-12
  • 打赏
  • 举报
回复
学习
Quady515 2003-03-12
  • 打赏
  • 举报
回复
看看pipe先.
chenxin790311 2003-03-11
  • 打赏
  • 举报
回复
up,因为有点忙,先做个标记吧。觉的楼上的pipe挺不错的
Quady515 2003-03-11
  • 打赏
  • 举报
回复
下班了,明天再来,

100分太少吗?其它人怎么不来呢?
用户 昵称 2003-03-11
  • 打赏
  • 举报
回复
some code FYI

功能:进程间的通讯-----使用匿名管道
'环境:vb60 + win2k/win9k 测试下通过

''发送方
Option Explicit

Private Declare Function CreatePipe Lib "kernel32" (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes As SECURITY_ATTRIBUTES, ByVal nSize As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long

Private Const INVALID_HANDLE_VALUE = -1
Private Const STARTF_USESTDHANDLES = &H100
Private Const STARTF_USESHOWWINDOW = &H1
Private Const SW_HIDE = 0
Private Const STD_ERROR_HANDLE = -12&
Private Const STD_OUTPUT_HANDLE = -11&
Private Const HIGH_PRIORITY_CLASS = &H80

Dim m_lngHWrite As Long '写管道名柄

'启动进程信息
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type

'进程信息
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type

'安全属性
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type

'将数据写入管道
Public Function SendDataToPrintApp(ByVal strBuf As String) As Boolean
Dim lngBufSize As Long
Dim lngWriteByte As Long
Dim lngRet As Long

strBuf = strBuf & Chr(0)

lngBufSize = LenB(StrConv(strBuf, vbFromUnicode)) '取发送数据的实际字节
lngRet = WriteFile(m_lngHWrite, ByVal strBuf, lngBufSize + 1, lngWriteByte, ByVal 0&) '将数据写入管道

If lngRet = 0 Then
SendDataToPrintApp = False
Else
SendDataToPrintApp = True
End If
End Function

'建立共享匿名管道
Public Function CreateSharePipe() As Boolean
On Error Resume Next
Dim lngHRead As Long
Dim lngWriteByte As Long
Dim lngBufSize As Long
Dim sec_attr As SECURITY_ATTRIBUTES
Dim proc_info As PROCESS_INFORMATION
Dim lngRet As Long
Dim start_info As STARTUPINFO
Dim strCmdLine As String

sec_attr.nLength = Len(sec_attr)
sec_attr.bInheritHandle = True

lngRet = CreatePipe(lngHRead, m_lngHWrite, sec_attr, ByVal 4096&) '建立管道 0失败

If lngRet <> 0 Then
start_info.cb = Len(start_info)
start_info.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
start_info.hStdInput = lngHRead '重置子进程的输入设备为读管道的句柄
start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE) '置子进程的输出错误设备为标准设备
start_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE) '置子进程的输出设备为标准输出设备

start_info.wShowWindow = SW_HIDE
If Right(App.Path, 1) <> "\" Then
strCmdLine = App.Path & "\PrintBill.Exe" & Chr(0)
Else
strCmdLine = App.Path & "PrintBill.Exe" & Chr(0)
End If

'创建子进程
lngRet = CreateProcess(vbNullString, strCmdLine, ByVal 0&, ByVal 0&, True, HIGH_PRIORITY_CLASS, ByVal 0&, vbNullString, start_info, proc_info)

If lngRet <> 0 Then
Call CloseHandle(proc_info.hThread)
Call CloseHandle(lngHRead) '因为本应用只写管道不读管道,所以关闭读管道句柄
CreateSharePipe = True

frm_IPOS_Login.txtUser.SetFocus
Else
CreateSharePipe = False
Call CloseHandle(lngHRead) '因为本应用只写管道不读管道,所以关闭读管道句柄
End If
Else
CreateSharePipe = False
End If
End Function


'''''接收方
Option Explicit

Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
Private Declare Function PeekNamedPipe Lib "kernel32" (ByVal hNamedPipe As Long, lpBuffer As Any, ByVal nBufferSize As Long, lpBytesRead As Long, lpTotalBytesAvail As Long, lpBytesLeftThisMessage As Long) As Long

Private Const STD_INPUT_HANDLE = -10&
Private Const MEM_SIZE = 4096

Private m_lngHPipeRead As Long

Private Sub Form_Load()
Dim blnret As Boolean
m_lngHPipeRead = GetStdHandle(STD_INPUT_HANDLE)
Me.Hide
End Sub

Private Sub Timer1_Timer()
Call ReadData
End Sub

Private Sub ReadData()
On Error Resume Next

Dim lngRet As Long
Dim strBuf As String
Dim lngRealRead As Long
Dim lngBufLen As Long
Dim str As String

Timer1.Enabled = False
strBuf = String(MEM_SIZE, " ")

str = Space(1)

Call PeekNamedPipe(m_lngHPipeRead, ByVal str, ByVal 1&, lngBufLen, ByVal 0&, ByVal 0&)

If lngBufLen > 0 Then
lngBufLen = Len(strBuf)
lngRet = ReadFile(m_lngHPipeRead, ByVal strBuf, lngBufLen, lngRealRead, ByVal 0&)
strBuf = Left(strBuf, InStr(1, strBuf, Chr(0)))
End If

Timer1.Enabled = True
End Sub
Quady515 2003-03-11
  • 打赏
  • 举报
回复
An application sends the WM_COPYDATA message to pass data to another application.

To send this message, call the SendMessage function with the following parameters (do not call the PostMessage function).
...
(摘自MSDN)

WM_COPYDATA不能用在postmessage中

Quady515 2003-03-11
  • 打赏
  • 举报
回复
试试wm_copydata先

我是从线程里往另一进程的窗体发消息
用户 昵称 2003-03-11
  • 打赏
  • 举报
回复
像线程发送消息需要使用
Public Declare Function PostThreadMessage Lib "user32" Alias "PostThreadMessageA" (ByVal idThread As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

而创建线程的时候可以指定一个窗口的句柄

如果传送字符串可以使用WM_COPYDATA消息,LPARAM是字符串地址。
Quady515 2003-03-11
  • 打赏
  • 举报
回复
朋友们帮帮忙吧!
Quady515 2003-03-11
  • 打赏
  • 举报
回复
不行
Accelerator 2003-03-11
  • 打赏
  • 举报
回复
去掉那些0试试
Quady515 2003-03-11
  • 打赏
  • 举报
回复
但是在线程中SendMessage之后就死了,更本没有机会发个消息回去。
Quady515 2003-03-11
  • 打赏
  • 举报
回复
'刚刚的“接收”COPY中有个错误
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'On Error GoTo ErrMin:
Dim sInfo As String
Dim bBuffer() As Byte

sInfo = String(128, Chr(0))

Select Case uMsg
Case WM_DTSInfo
CopyMemory ByVal StrPtr(sInfo), ByVal lParam, wParam
bBuffer = StrConv(sInfo, vbUnicode)
frmMain.lstInfo.AddItem bBuffer
Case Else
WindowProc = CallWindowProc(pOldProc, hwnd, uMsg, wParam, lParam)
End Select

Exit Function
ErrMin:
End Function
Quady515 2003-03-11
  • 打赏
  • 举报
回复
'发送
Private Function SendMSG(ByVal hWnd As Long, ByVal sSendText As String) As Boolean

Dim bBuffer() As Byte
Dim bBuffer2() As Byte
Dim lLen As Long

lLen = Len(sSendText)
bBuffer = StrConv(sSendText, vbFromUnicode)

ReDim bBuffer2(lLen + 1)
Call RtlMoveMemory(bBuffer2(0), bBuffer(0), lLen)

' SendMessage hWnd2, WM_DTSInfo, lLen + 1, bBuffer2(0)
PostMessage hWnd2, WM_DTSInfo, lLen + 1, ByVal StrPtr(bBuffer2(0))
End Function

'接收
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'On Error GoTo ErrMin:
Dim sInfo As String
Dim bBuffer() As Byte

sInfo = String(128, Chr(0))

Select Case uMsg
Case WM_DTSInfo
CopyMemory ByVal StrPtr(sInfo), ByVal lParam, wParam
bBuffer = StrConv(sInfo, vbUnicode)
frmMain.lstInfo.AddItem bBuffer
End If
Case Else
WindowProc = CallWindowProc(pOldProc, hwnd, uMsg, wParam, lParam)
End Select

Exit Function
ErrMin:
End Function
加载更多回复(9)
在C#中SendMessage和PostMessage的参数传递 在C#中可以使用Window API提供的SendMessage和PostMessage来传递参数。两者的区别简单介绍下:返回值的不同,我们先看一下 MSDN 里的声明: LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); 其中 4 个参数的意义是一样的,返回值类型不同(其实从数据上看他们一样是一个 32 位的数,只是意义不一样),LRESULT 表示的是消息被处理后的返回值,BOOL 表示的是消息是不是 Post 成功。 2、PostMessage 是异步的,SendMessage 是同步的。 PostMessage 只把消息放入队列,不管消息是否被处理就返回,消息可能不被处理;而 SendMessage 等待消息被处理完了之后才返回,如果消息不被处理,发送消息的线程将一直被阻塞。 3、如果在同一个线程内,SendMessage 发送消息时,由 USER32.DLL 模块调用目标窗口的消息处理程序,并将结果返回。SendMessage 在同一线程中发送消息并不入线程消息队列。PostMessage 发送消息时,消息要先放入线程的消息队列,然后通过消息循环分派到目标窗口(DispatchMessage)。 如果在不同线程内,SendMessage 发送消息到目标窗口所属线程的消息队列,然后发送消息的线程在 USER32.DLL 模块内监视和等待消息处理,直到目标窗口处理完返回。SendMessage 在返回前还做了很多工作,比如,响应别的线程向它 SendMessage。Post 到别的线程时,最好用 PostThreadMessage 代替 PostMessage,PostMessage 的 hWnd 参数可以是 NULL,等效于 PostThreadMessage + GetCurrentThreadId。Post WM_QUIT 时,应使用 PostQuitMessage 代替。 4、系统只整编(marshal)系统消息(0 到 WM_USER 之间的消息),发送用户消息(WM_USER 以上)到别的进程时,需要自己做整编。 用 PostMessage、SendNotifyMessage、SendMessageCallback 等异步函数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息的处理就返回,接受者还没处理指针就已经被释放了。 5、在 Windows 2000/XP 里,每个消息队列最多只能存放 10,000 个 Post 的消息,超过的还没被处理的将不会被处理,直接丢掉。这个值可以改得更大:[HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/Windows] USERPostMessageLimit,最小可以是 4000。 PostMessage只负责将消息放到消息队列中,不确定何时及是否处理 SendMessage要等到受到消息处理的返回码(DWord类型)后才继续 PostMessage执行后马上返回 SendMessage必须等到消息被处理后才会返回。

1,488

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧