我有一个使用紧凑框架(NETCF)的Windows Mobile应用程序,我想响应某人按下发送键并让电话拨打我的应用程序中选择的号码。有没有办法使用紧凑的框架来捕获发送密钥?我已经看了几篇关于捕获键的文章,但是我没有找到一个包含“发送”键的文章。
更新:
我在Windows Mobile上发现了一篇描述SetWindowsHookEx作为未记录的API的文章。如果是这种情况,那么我真的不想使用它。
SetWindowsHookEx on Windows Mobile
在进行了更多搜索后,我发现“发送”键在Windows Mobile术语中称为“Talk”键。然后,我发现了一篇关于使用SHCMBM_OVERRIDEKEY消息的博客帖子,用于通知操作系统在用户按下Talk键时向我的应用发送WM_HOTKEY消息。
Jason Fuller Blog post about using the Talk button
博客文章及其指出的文档似乎正是我正在寻找的内容。我找不到一个有效的例子,我发现很多人都无法使用它。 SmartPhones也不支持VK_TTALK。我很想听听那些在智能手机和PocketPC手机上工作的人。
答案 0 :(得分:3)
我可以确认使用SHCMBM_OVERRIDEKEY可以在PPC和SP设备上运行。我在WM5 PPC,WM5 SP,WM6 PPC,WM6 SP上进行了测试。我还没有尝试过WM6.1或WM6.5,但我认为它们可以工作,因为WM6可以工作。
您也可能需要在通话期间支持DTMF?
由于我正在编写LAP dll,因此我按照以下页面进行操作: LAP Implementation Issues
这些示例在C中,因此您必须将它们转换为C#。
要为特定窗口设置陷阱“talk”键,您需要执行以下操作:
SendMessage(SHFindMenuBar(window_hwnd),
SHCMBM_OVERRIDEKEY,
VK_TTALK,
MAKELPARAM((SHMBOF_NODEFAULT|SHMBOF_NOTIFY), (SHMBOF_NODEFAULT|SHMBOF_NOTIFY));
您可以随时打开/关闭陷阱。要轻松关闭陷阱:
SendMessage(SHFindMenuBar(window_hwnd),
SHCMBM_OVERRIDEKEY,
VK_TTALK,
MAKELPARAM(0, (SHMBOF_NODEFAULT|SHMBOF_NOTIFY));
要检测何时按下'Talk'键,您需要在窗口proc上捕获WM_HOTKEY窗口消息:
case WM_HOTKEY:
switch(HIWORD(lParam))
{
case VK_TTALK:
// make ph call
break;
}
return TRUE;
要拨打电话,您需要使用“PhoneMakeCall”API:
#include <phone.h>
void MakePhoneCall(const wchar_t* number)
{
PHONEMAKECALLINFO call;
memset(&call, 0x0, sizeof(PHONEMAKECALLINFO));
call.cbSize = sizeof(PHONEMAKECALLINFO);
call.dwFlags = PMCF_DEFAULT;
call.pszDestAddress = number;
PhoneMakeCall(&call);
}
要在通话过程中支持DTMF,您需要使用SNAPI跟踪来电(我相信有一个C#库可以帮助您SystemProperty)。
开始通话后设置:
#include <snapi.h>
RegistryNotifyWindow(SN_PHONEACTIVECALLCOUNT_ROOT, SN_PHONEACTIVECALLCOUNT_PATH, SN_PHONEACTIVECALLCOUNT_VALUE, window_hwnd, callback_window_msg_number /*e.g. WM_APP */, 0, NULL, &phone_call_notify_handle);
当呼叫计数发生变化时,您将通过提供的窗口消息回叫。您需要阅读注册表并检查呼叫计数是否降至零。如果是,您需要关闭SNAPI句柄:
RegistryCloseNotification(phone_call_notify_handle);
在通话中,使用用户按下的键向cprog应用程序发送消息:
#define WM_CPROG_SEND_VKEY_DTMF (WM_APP+3) // Sends the DTMF tone(s) through to the current call (converting from VKEY to DTMF chars)
BOOL PhoneSendDTMF(UINT uvKey)
{
BOOL bRet = FALSE;
static HWND s_hwndCProg = NULL;
TCHAR chDTMF = MapVKeyToChar(uvKey);
// Attempt to find the cprog window (MSCprog).
// Try to keep this window handle cached.
if(NULL == s_hwndCProg || !IsWindow(s_hwndCProg))
{
s_hwndCProg = FindWindow(TEXT("MSCprog"), NULL);
}
// Send WM_CPROG_SEND_VKEY_DTMF to the CProg window.
if(NULL != s_hwndCProg)
{
bRet = BOOLIFY(PostMessage(s_hwndCProg,
WM_CPROG_SEND_VKEY_DTMF, (WPARAM)chDTMF, 0));
}
return bRet;
}
答案 1 :(得分:2)
你可以通过一个keyhook来捕捉世界上的所有键(除了桌面上的CTRL + ALT + DEL):
您可以通过coredll.dll(而不是user32)在CE中使用此(或其他一个覆盖)。
但是,这不在.NET Compact Framework中,需要P / Invoke。 “免费”按键的最佳乐趣是Form.KeyPreview = true;并且只会在表单聚焦时为您提供被击中的键,有时在处理具有特殊键的设备时可能没有(可能是您的“发送”键,因为我在Intermec上遇到类似“Application1”键的情况一段时间后单位。)
但是有一个很棒的选择,我相信OpenNETCF either already does or will very soon roll with a keyhook(通过上面的WinAPI调用)公开了一个令人愉快的托管包装器。快乐!
如果尚未准备就绪,那么有大量文章和代码可以证明如何通过Google使用此功能,因此在最糟糕的情况下,如果您执行this之类的搜索,您应该可以找到一些内容。也许像this?
答案 2 :(得分:0)
在使用指定的PhoneMakeCall背后是否有一些特殊的理由?它适用于智能手机和Windows Mobile 6 Professional。
编辑:我误解了这个问题。我现在看到你想陷阱发送事件。不过,我让我的回答留下来作为参考。