虚拟键盘的显示和关闭

宇宙379 2015-07-06 03:35:26
我需要做一个触摸屏程序,无鼠标和键盘。
CEdit setfocus调出虚拟键盘osk.exe,killFocus关闭他。
现在有几个问题:
1. 发关闭消息无法关闭(可以找到句柄);
2. 程序最小化后再show就不出来了(还在最小化状态);
3. 还有个问题,手动关闭为什么卡?
代码:

void CLoginDlg::OnEnSetfocusEditPwd()
{
HWND hwnd = ::FindWindow(NULL, _T("屏幕键盘"));
if (hwnd == NULL){
PVOID OldValue;
BOOL bRet = Wow64DisableWow64FsRedirection(&OldValue);
ShellExecute(this->GetSafeHwnd(), _T("open"), _T("osk.exe"), _T(""), _T(""), SW_SHOW);
if (bRet) {
Wow64RevertWow64FsRedirection(OldValue);
}
}
else{
::ShowWindow(hwnd, SW_SHOWNORMAL);
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
}
void CLoginDlg::OnEnKillocusEditPwd()
{
HWND hwnd = ::FindWindow(NULL, _T("计算器"));
if (hwnd){
::SendMessage((HWND)hwnd, WM_CLOSE, 0, 0);
}
}
...全文
837 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
宇宙379 2015-07-07
  • 打赏
  • 举报
回复
引用 10 楼 pcradio 的回复:
osk.exe它本身有判断是否进程已启动逻辑的,如果你已经启动了,多次启动也不会产生多个进程的,计算器它没有这个逻辑,你可以自己去判断计算器进程或者窗口是否存在,如果存在你就不创建进程
恩,谢谢
阿源是少年 2015-07-06
  • 打赏
  • 举报
回复
osk.exe它本身有判断是否进程已启动逻辑的,如果你已经启动了,多次启动也不会产生多个进程的,计算器它没有这个逻辑,你可以自己去判断计算器进程或者窗口是否存在,如果存在你就不创建进程
宇宙379 2015-07-06
  • 打赏
  • 举报
回复
引用 8 楼 pcradio 的回复:
这是我的响应代码,没什么问题,最小化也是可以的:
void CInvokeOSKDlg::OnSetFocus()
{
	PVOID oldValue = NULL;
	f_Wow64DisableWow64FsRedirection(&oldValue);
	ShellExecute(NULL, "open", "osk.exe", NULL, NULL, SW_SHOW);
	f_Wow64RevertWow64FsRedirection(oldValue);
}

void CInvokeOSKDlg::OnKillFocus()
{
	DWORD dwId = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	PROCESSENTRY32 pe;
	Process32First(hSnapshot,&pe);
	do
	{
		if(!_tcscmp(pe.szExeFile, _T("osk.exe")))
		{
			dwId = pe.th32ProcessID;
			break;
		}
	}
	while(Process32Next(hSnapshot,&pe));
	CloseHandle(hSnapshot);
	
	if(dwId)
	{
		HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, NULL, dwId);
		if(hProcess)
			TerminateProcess(hProcess, 0);
	}
}
谢谢了,差不多吧,不过关闭好像不得行,我用的是: void CloseProgram(CString strProgram) { HANDLE handle; //定义CreateToolhelp32Snapshot系统快照句柄 HANDLE handle1; //定义要结束进程句柄 handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//获得系统快照句柄 PROCESSENTRY32 *info; //定义PROCESSENTRY32结构字指 //PROCESSENTRY32 结构的 dwSize 成员设置成 sizeof(PROCESSENTRY32) info = new PROCESSENTRY32; info->dwSize = sizeof(PROCESSENTRY32); //调用一次 Process32First 函数,从快照中获取进程列表 Process32First(handle, info); //重复调用 Process32Next,直到函数返回 FALSE 为止 while (Process32Next(handle, info) != FALSE) { CString strTmp = info->szExeFile; //指向进程名字 //strcmp字符串比较函数同要结束相同 //if(strcmp(c, info->szExeFile) == 0 ) if (strProgram.CompareNoCase(info->szExeFile) == 0) { //PROCESS_TERMINATE表示为结束操作打开,FALSE=可继承,info->th32ProcessID=进程ID handle1 = OpenProcess(PROCESS_TERMINATE, FALSE, info->th32ProcessID); //结束进程 TerminateProcess(handle1, 0); } } delete info; CloseHandle(handle); }这个可以。 还有每次setfoucus 都调出一个osk.exe? 好像只有一个屏幕键盘,但是调用计算器什么的就很多了。 谢了,明天结贴了。
阿源是少年 2015-07-06
  • 打赏
  • 举报
回复
这是我的响应代码,没什么问题,最小化也是可以的:
void CInvokeOSKDlg::OnSetFocus()
{
	PVOID oldValue = NULL;
	f_Wow64DisableWow64FsRedirection(&oldValue);
	ShellExecute(NULL, "open", "osk.exe", NULL, NULL, SW_SHOW);
	f_Wow64RevertWow64FsRedirection(oldValue);
}

void CInvokeOSKDlg::OnKillFocus()
{
	DWORD dwId = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	PROCESSENTRY32 pe;
	Process32First(hSnapshot,&pe);
	do
	{
		if(!_tcscmp(pe.szExeFile, _T("osk.exe")))
		{
			dwId = pe.th32ProcessID;
			break;
		}
	}
	while(Process32Next(hSnapshot,&pe));
	CloseHandle(hSnapshot);
	
	if(dwId)
	{
		HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, NULL, dwId);
		if(hProcess)
			TerminateProcess(hProcess, 0);
	}
}
阿源是少年 2015-07-06
  • 打赏
  • 举报
回复
如果是直接点主程序的最小化按钮,不kill进程也是可以的,你的代码我跑起来了的,我的OS 是win7 64,如果是32的,就不要用 PVOID OldValue; BOOL bRet = Wow64DisableWow64FsRedirection(&OldValue); ShellExecute(this->GetSafeHwnd(), _T("open"), _T("osk.exe"), _T(""), _T(""), SW_SHOW); if (bRet) { Wow64RevertWow64FsRedirection(OldValue); }
宇宙379 2015-07-06
  • 打赏
  • 举报
回复
引用 4 楼 pcradio 的回复:
1.改成::FindWindow(NULL, _T("屏幕键盘“));就可以关了 2.最小化再不能显示问题,你点最小化按钮最小化键盘时,键盘或获取焦点,导致你的程序执行了KillFocus,这样键盘会被kill掉,但是有个奇怪的问题就是键盘窗口销毁了,但是进程并未被杀死,这就导致你下次SetFocus时无法启动键盘,因为进程一直都在,不会重复启动,所以在killFocus里面,你要直接kill osk.exe进程,OnEnKillocusEditPwd()里代码如下:
	#include <Tlhelp32.h> 
        DWORD dwId = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	PROCESSENTRY32 pe;
	Process32First(hSnapshot,&pe);
	do
	{
		if(!_tcscmp(pe.szExeFile, _T("osk.exe")))
		{
			dwId = pe.th32ProcessID;
			break;
		}
	}
	while(Process32Next(hSnapshot,&pe));
	CloseHandle(hSnapshot);
	
	if(dwId)
	{
		HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, NULL, dwId);
		if(hProcess)
			TerminateProcess(hProcess, 0);
	}
谢谢,关闭这样可以,但是最小化还是不能显示,和kill进程无关
宇宙379 2015-07-06
  • 打赏
  • 举报
回复
引用 3 楼 pcradio 的回复:
void CLoginDlg::OnEnKillocusEditPwd() { HWND hwnd = ::FindWindow(NULL, _T("计算器")); if (hwnd){ ::SendMessage((HWND)hwnd, WM_CLOSE, 0, 0); } 为什么你拿“计算器”的句柄了?不是“屏幕键盘”吗!
哦,不好意思,我程序是屏幕键盘,写错了
阿源是少年 2015-07-06
  • 打赏
  • 举报
回复
1.改成::FindWindow(NULL, _T("屏幕键盘“));就可以关了 2.最小化再不能显示问题,你点最小化按钮最小化键盘时,键盘或获取焦点,导致你的程序执行了KillFocus,这样键盘会被kill掉,但是有个奇怪的问题就是键盘窗口销毁了,但是进程并未被杀死,这就导致你下次SetFocus时无法启动键盘,因为进程一直都在,不会重复启动,所以在killFocus里面,你要直接kill osk.exe进程,OnEnKillocusEditPwd()里代码如下:
	#include <Tlhelp32.h> 
        DWORD dwId = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	PROCESSENTRY32 pe;
	Process32First(hSnapshot,&pe);
	do
	{
		if(!_tcscmp(pe.szExeFile, _T("osk.exe")))
		{
			dwId = pe.th32ProcessID;
			break;
		}
	}
	while(Process32Next(hSnapshot,&pe));
	CloseHandle(hSnapshot);
	
	if(dwId)
	{
		HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, NULL, dwId);
		if(hProcess)
			TerminateProcess(hProcess, 0);
	}
阿源是少年 2015-07-06
  • 打赏
  • 举报
回复
void CLoginDlg::OnEnKillocusEditPwd() { HWND hwnd = ::FindWindow(NULL, _T("计算器")); if (hwnd){ ::SendMessage((HWND)hwnd, WM_CLOSE, 0, 0); } 为什么你拿“计算器”的句柄了?不是“屏幕键盘”吗!
宇宙379 2015-07-06
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
WinExec("osk.exe",SW_SHOW);
WinExec("cmd.exe /c taskkill /IM osk.exe",SW_HIDE);
谢谢,但是我试过了还是不行。 关不了
赵4老师 2015-07-06
  • 打赏
  • 举报
回复
WinExec("osk.exe",SW_SHOW);
WinExec("cmd.exe /c taskkill /IM osk.exe",SW_HIDE);

15,978

社区成员

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

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