WndProc接收不到信息,请大家帮忙参考下

qiushenwei88 2012-08-06 10:01:01
我有个USB按键,要捕获到按键信息,有个VB程序,按键按下时VB能接收到信息,现在用BCB我做了没有接收到信息,请大家帮帮忙。
VB程序是这样的
Public Const WM_USER = &H400
Public Const WM_SNAP_KEYDOWN = WM_USER + &H3523

Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long

If uMsg = WM_SNAP_KEYDOWN Then
Call ProcessSnapShot
End If

Dim lpPrevWndProc As Long
'查询原来默认的窗口过程指针
lpPrevWndProc = GetWindowLong(hw, GWL_USERDATA)
'调用原来的窗口过程
WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)

End Function

BCB程序:
.h里面:
#define WM_SNAP_KEYDOWN (WM_USER + 0x3523)
void __fastcall WndProc(TMessage & msg);

.cpp里面:
void __fastcall TfMain::WndProc(TMessage & msg)
{
if( msg.Msg == WM_SNAP_KEYDOWN )
ShowMessage("ooo");

TForm::WndProc(msg);

}
总是接收不到,不知问题出在哪里

...全文
564 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
fxworld 2012-08-06
  • 打赏
  • 举报
回复

HYImage1->RegNotifyWnd((int)this->Handle, True)这个就是传窗口句柄,有可能该函数调用后你的TfMain发生了改变导致原来的Handle无效。
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
Me.Tag = Hook(Me.hWnd)

bResult = HYImage1.OpenDevice(0)
bResult = HYImage1.RegNotifyWnd(Me.hWnd, True)//VB中这个注释掉就捕获不到按键

BCB中HYImage1->RegNotifyWnd((int)this->Handle, True)//这样也捕获不到,请问如何传递窗口句柄给消息
fxworld 2012-08-06
  • 打赏
  • 举报
回复
这和传统不传统的没有关系,BEGIN_MESSAGE_MAP结构编译时是被扩展到WndProc里的,直接用WndProc更方便。


可以检查一下是否需要传递窗口句柄给消息发送端,或者检查发送端有没有发送给你的TfMain。
我不懂电脑 2012-08-06
  • 打赏
  • 举报
回复
还是用传统的C++ Builer的自定义消息处理办法吧:

对自定义消息的处理
  在有的情况下,程序需要发送自己定义的消息,它既可以用在两个应用程序之间的通讯,也可以用在一个程序内部的不同窗体和组件之间的通信。使用自定义消息有两个优点:一是发消息时,无须知道接受者的具体类型,只要知道窗口的句柄;二是消息可以广播给多个接受者。它也有静态和动态的两种函数响应映射关系。
  同样举一个例子,在窗体类的头文件(.h)中加入自定义消息MY_SELFDEFINE,并静态的对这个自定义消息建立函数映射关系
……
#define MY_SELFDEFINE (WM_USER+100)
……
//定义响应函数
void __fastcall Handle(TMessage & Msg);
……
//建立响应函数(Handle)与自定义消息(MY_SELFDEFINE)的映射
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(MY_SELFDEFINE,TMessage,Handle)
//VCL_MESSAGE_HANDLER(MY_SELFDEFINE,TMessage,Handle)
END_MESSAGE_MAP(TForm)
……
在窗体类的实现文件中(.cpp)分别实现定义的响应函数(Handle)和发送自定义的消息(MY_SELFDEFINE)
……
//响应函数的实现
void __fastcall TMsgExp::Handle(TMessage & Msg)
{
ShowMessage("拦截到自定义消息MY_SELFDEFINE");
}
……
//发送自定义的消息(MY_SELFDEFINE)
this->Perform(MY_SELFDEFINE,0,0);
  应用程序接受到自定义的消息后,根据静态建立的映射关系,将消息交由响应函数处理。
  接着上面的例子,再建立一个动态对自定义消息进行响应的例子。分别建立两个响应函数: OpenForm(打开新窗口)和CloseForm(关闭新窗口)。
void __fastcall TMsgExp::OpenForm(TMessage & Msg)
{
//截获到MY_SELFDEFINE消息,则打开新窗口,否则交由原来的函数处理
if (Msg.Msg == MY_SELFDEFINE)
NewWindows->Show();
else
WndProc(Msg);
}
……
void __fastcall TMsgExp::CloseForm(TMessage & Msg)
{
//截获到MY_SELFDEFINE消息,则关闭新窗口,否则交由原来的函数处理
if (Msg.Msg == MY_SELFDEFINE)
NewWindows->Hide();
else
WndProc(Msg);
}
……
//根据单选按钮的不同状态,动态建立自定义消息与响应函数的映射
if (RadioButton3->Checked)
/*利用TControl控件的WindowProc属性,动态地设置
对处理消息的响应函数*/
this->WindowProc=OpenForm;
if (RadioButton4->Checked)
this->WindowProc=CloseForm;
//发送自定义的消息(MY_SELFDEFINE)
this->Perform(MY_SELFDEFINE,0,0);
……
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
也用新工程试了,还是收不到。
这个是一个usb视频卡,上面有个按键,能采集图像。就是想捕获这个信息的。
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
你在C++Builder中新建一个工程试试。
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
您是说我这段BCB代码没问题?不知道怎么收不到按键信息。
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
引用 1 楼 的回复:
那个VB程序中还有什么代码?

还有这些,不知道能不能用到
Public Function Hook(ByVal hWnd As Long) As Long
Dim pOld As Long
'指定自定义的窗口过程
pOld = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
……
[/Quote]

这段代码就是子类化窗口,实现对自定义消息的处理。在C++Builder中重载WndProc就可以实现。至于VC的那段,也是通过消息映射来实现对WM_SNAP_KEYDOWN的处理。代码看起来没什么问题。
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
我也有个VC程序,也能实现这个功能,请看下面:
.h:
afx_msg LRESULT OnUsbKeyDown(WPARAM wParam,LPARAM lParam);
.cpp:
BEGIN_MESSAGE_MAP(CUCDemoDlg, CDialog)
ON_MESSAGE(WM_SNAP_KEYDOWN,OnUsbKeyDown)
END_MESSAGE_MAP()

LRESULT CUCDemoDlg::OnUsbKeyDown(WPARAM wParam,LPARAM lParam)
{
LONG nIndex = (LONG)wParam;

if(m_VideoContainer.IsValidIndex(nIndex))
{
m_VideoContainer.SetActiveIndex(nIndex);

CMediaChannel *pMediaChannel = GetActiveChannel();

if(pMediaChannel != NULL)
{
if(pMediaChannel->m_bButtonSnap)
{
if(m_btn_StartSnap.IsWindowEnabled())
OnButtonStartsnap();
}
else
OnButtonRecord();
}
}

return 0;
}
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
那个VB程序中还有什么代码?
[/Quote]
还有这些,不知道能不能用到
Public Function Hook(ByVal hWnd As Long) As Long
Dim pOld As Long
'指定自定义的窗口过程
pOld = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
'保存原来默认的窗口过程指针
SetWindowLong hWnd, GWL_USERDATA, pOld
Hook = pOld
End Function
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
那个VB程序中还有什么代码?
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
问题解决就及时结帖,谢谢。
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]
if( msg.WParam == WM_SNAP_KEYDOWN )

改成:

if( msg.Msg == WM_SNAP_KEYDOWN )
[/Quote]

谢谢ccrun,现在可以了,我开始是用Msg的,没接收到信息,所以改为WParam ,就忘记改回来了,接收批评。
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
楼主,写代码要认真一些啊。马虎是程序员的最大的敌人。
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
if( msg.WParam == WM_SNAP_KEYDOWN )

改成:

if( msg.Msg == WM_SNAP_KEYDOWN )
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]
好了,现在发一下你在C++Builder中的代码。
[/Quote]

.h:
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "HYIMAGELib_OCX.h"
#include <Buttons.hpp>
#include <OleCtrls.hpp>
//---------------------------------------------------------------------------
#define WM_SNAP_KEYDOWN (WM_USER + 0x3523)



class TForm1 : public TForm
{
__published: // IDE-managed Components
THYImage *HYimg;
TBitBtn *btnOpenDevice;
TBitBtn *btnCloseDevice;
void __fastcall btnOpenDeviceClick(TObject *Sender);
void __fastcall btnCloseDeviceClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall WndProc(TMessage & msg);
protected:

};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

.cpp:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "HYIMAGELib_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btnOpenDeviceClick(TObject *Sender)
{
bool bResult;
bResult = HYimg->OpenDevice(0) ;
bResult = HYimg->RegNotifyWnd( (int)Handle , true) ;
bResult = HYimg->StartPreview();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btnCloseDeviceClick(TObject *Sender)
{
HYimg->StopPreview();
HYimg->CloseDevice();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::WndProc(TMessage & msg)
{
if( msg.WParam == WM_SNAP_KEYDOWN )
ShowMessage("ooo");

TForm::WndProc(msg); //
}
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
好了,现在发一下你在C++Builder中的代码。
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
ProcessSnapShot就是采集图片,可以不管
Call ProcessSnapShot 这句可以改为 MsgBox "ok"
qiushenwei88 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]
坦白说吧,你的VB代码中还有些啥,一次性的全贴出来吧,别让哥几个扭扭捏捏的猜谜语了。
[/Quote]
那我就把VB所有代码都发过来吧,下面是Module里面:
Option Explicit
Private Const GWL_WNDPROC = -4
Public Const GWL_USERDATA = (-21)
Public Const WM_SIZE = &H5
Public Const WM_USER = &H400
Public Const WM_SNAP_KEYDOWN = WM_USER + &H3523
Dim Deal_Snap_Btn As Long
Dim Deal_Snap_Form As Form

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
Public Declare Function GetWindowLong Lib "user32" Alias _
"GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long

Private Declare Function SetWindowLong Lib "user32" Alias _
"SetWindowLongA" (ByVal hWnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long

Public Function Hook(ByVal hWnd As Long) As Long
Dim pOld As Long
'指定自定义的窗口过程
pOld = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
'保存原来默认的窗口过程指针
SetWindowLong hWnd, GWL_USERDATA, pOld
Hook = pOld
End Function

Public Sub Unhook(ByVal hWnd As Long, ByVal lpWndProc As Long)
Dim temp As Long
'Cease subclassing.
temp = SetWindowLong(hWnd, GWL_WNDPROC, lpWndProc)
End Sub

Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long

If uMsg = WM_SNAP_KEYDOWN Then
Call ProcessSnapShot
End If

Dim lpPrevWndProc As Long
'查询原来默认的窗口过程指针
lpPrevWndProc = GetWindowLong(hw, GWL_USERDATA)
'调用原来的窗口过程
WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)

End Function

Public Sub ProcessSnapShot()
Dim nResult As Boolean
Dim nMemSize As Long
Dim hMemHandle As OLE_HANDLE
Dim nBuffer As Long

nMemSize = Form1.HYImage1.GetImgBufsize()

hMemHandle = Form1.HYImage1.AllocMem(nMemSize, 1) '(1代表分配1个内存块,大小为nMemSize,注意,这个地方定义里面的两个参数名称搞反了,提供参数的时候需要反着来理解)

nBuffer = Form1.HYImage1.GetMemAt(hMemHandle, 0)

nResult = Form1.HYImage1.StartSnapShot(1, 1000)

nResult = Form1.HYImage1.GetMemSnapA(nBuffer, nMemSize, 1000)

'通过以上步骤,抓图映像已经存到了nBuffer开头的数组里,下面就可以使用这个数组进行存储或显示

'如:
'SnapWnd.Refresh

nResult = Form1.HYImage1.PaintMemImgA(nBuffer, nMemSize, Form1.SnapWnd.hWnd)

Form1.HYImage1.EndPaint (Form1.SnapWnd.hWnd) '释放由于PaintMemImgA占用的窗口句柄

nResult = Form1.HYImage1.SaveImgAsBmpA(nBuffer, nMemSize, "c:\\ImageSnap.bmp")

Form1.HYImage1.FreeMem (hMemHandle)

Form1.HYImage1.CancelSanp '结束本次快照

End Sub

下面是窗体一个按键,预览图像
Private Sub Command6_Click()
Dim bResult As Boolean


Me.Tag = Hook(Me.hWnd)

bResult = HYImage1.OpenDevice(0)
bResult = HYImage1.RegNotifyWnd(Me.hWnd, True)

HYImage1.StartPreview
End Sub

别的没有了。
ccrun.com 2012-08-06
  • 打赏
  • 举报
回复
坦白说吧,你的VB代码中还有些啥,一次性的全贴出来吧,别让哥几个扭扭捏捏的猜谜语了。
加载更多回复(2)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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