关于点击编辑框然后弹出输入键盘的焦点问题

凌乱哥 2014-09-09 11:40:05
一个主程序exe,界面有输入框等控件
一个单独的exe,运行后是一个置顶的窗口,上面绘制了很多格子,用于模拟键盘

目的是要在单击主程序的编辑框的时候,调用键盘程序并实现可输入,所以我在编辑框的“得到焦点”事件中ShellExecute了键盘程序,但是出现的情况就是:起初编辑框显示“搜索...”,单击一下,“搜索”两字没了,键盘程序也起来了,但是,这键盘一起来,把编辑框的焦点抢掉了,编辑框又显示“搜索”,当然此时点键盘是无法输入的,要再点一下编辑框,有了输入焦点后,键盘才起了作用

所以问题就是,如何改掉这个调出键盘后还得再点一下编辑框的问题?就好像是要让键盘永远无法得到焦点一样,因为我发现Win8的屏幕键盘出现以后一直是非焦点状态的,除非你鼠标左键一直按着它
...全文
681 31 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
凌乱哥 2014-09-12
  • 打赏
  • 举报
回复
引用 23 楼 schlafenhamster 的回复:
我试了一下用 EXE 的, 你 传递参数方法可以, 但 要 2个 hWnd, 一个 是 你的 app 一个 是 Edit。 所以 源 文件 还是要改。 除了 gFocus 还要 一个 gApp。 另外 PreTranslateMessage 要改 ReleaseFocus 也要 改, 主要是 HWND wnd=::GetForeGroundWindow(); 现在 wnd 是 知道 的。 即: ::SetForeGroundWindow(gFocus); ::SetFocus(gFocus); 现在是: ::SetForeGroundWindow(gApp); ::SetFocus(gFocus); 你 初始化COnscreenKeyboardDlg 时: ShowWindow(SW_SHOWNA); return FALSE; 一开始 就可以 没 焦点。
非常感谢你耐心的解答和回复,我先尝试一下看看
凌乱哥 2014-09-12
  • 打赏
  • 举报
回复
引用 22 楼 zhllxt 的回复:
另外参考我以前发过的帖子,可以做出来一个完整的模拟键盘,这个帖子主要可以参考的地方是,如果全部用“画”的方式做一个模拟键盘:http://bbs.csdn.net/topics/390230336
多谢大哥再次相助!我觉得你这个完全符合我的要求,我试下,3Q
凌乱哥 2014-09-12
  • 打赏
  • 举报
回复

OnLButtonDown中
	m_bMouseDown = TRUE;
	m_ptStart = point;
	ClientToScreen(&m_ptStart);

OnLButtonUp中
m_bMouseDown = FALSE;

void CSKWindow::OnMouseMove(UINT nFlags, CPoint point)
{
	if(m_bMouseDown)
	{
		CPoint pt;
		::GetCursorPos(&pt);
		int xMove = pt.x - m_ptStart.x;
		int yMove = pt.y - m_ptStart.y;
		CRect rc;
		GetClientRect(&rc);
		ClientToScreen(&rc);
		MoveWindow(rc.left+xMove,rc.top+yMove,rc.Width(),rc.Height());
		m_ptStart = pt;
	}
	CWnd::OnMouseMove(nFlags,point);
}
凌乱哥 2014-09-12
  • 打赏
  • 举报
回复
引用 29 楼 zhllxt 的回复:
可以的,你参考这个帖子,有具体工程代码下载: http://bbs.csdn.net/topics/380267523
恩,明白你的意思了,测试OK,再次感谢
zhllxt 2014-09-12
  • 打赏
  • 举报
回复
可以的,你参考这个帖子,有具体工程代码下载: http://bbs.csdn.net/topics/380267523
凌乱哥 2014-09-12
  • 打赏
  • 举报
回复
引用 27 楼 zhllxt 的回复:
拖动的代码如下:其中有一些杂代码,你看看去掉即可。以前的代码了。
好像不太对哦,你看 CWnd * pParent = this; 。。。。。 pParent->MoveWindow(.....) 感觉你这是移动的对话框吧,不过我大概知道怎么做了,都怪我思维太死了,就只想着在鼠标按下时发送一个HTCAPTION的WM_NCLBUTTONDOWN消息来实现 键盘已经做的差不多了,在你的程序基础上修改了挺多了,改天分享出来。
schlafenhamster 2014-09-12
  • 打赏
  • 举报
回复
我试了一下用 EXE 的, 你 传递参数方法可以, 但 要 2个 hWnd, 一个 是 你的 app 一个 是 Edit。 所以 源 文件 还是要改。 除了 gFocus 还要 一个 gApp。 另外 PreTranslateMessage 要改 ReleaseFocus 也要 改, 主要是 HWND wnd=::GetForeGroundWindow(); 现在 wnd 是 知道 的。 即: ::SetForeGroundWindow(gFocus); ::SetFocus(gFocus); 现在是: ::SetForeGroundWindow(gApp); ::SetFocus(gFocus); 你 初始化COnscreenKeyboardDlg 时: ShowWindow(SW_SHOWNA); return FALSE; 一开始 就可以 没 焦点。
zhllxt 2014-09-12
  • 打赏
  • 举报
回复
拖动的代码如下:其中有一些杂代码,你看看去掉即可。以前的代码了。

#if !defined(AFX_DIALOG1_H__219A3285_6999_47A6_9064_66A70CAC0CCA__INCLUDED_)
#define AFX_DIALOG1_H__219A3285_6999_47A6_9064_66A70CAC0CCA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Dialog1.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CDialog1 dialog

class CDialog1 : public CDialog
{
// Construction
public:
	CDialog1(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
	//{{AFX_DATA(CDialog1)
	enum { IDD = IDD_DIALOG1 };
		// NOTE: the ClassWizard will add data members here
	//}}AFX_DATA
	BOOL m_bDraging;
	CPoint m_ptDrag;


// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CDialog1)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:

	// Generated message map functions
	//{{AFX_MSG(CDialog1)
	afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DIALOG1_H__219A3285_6999_47A6_9064_66A70CAC0CCA__INCLUDED_)


// Dialog1.cpp : implementation file
//

#include "stdafx.h"
#include "wpc.h"
#include "Dialog1.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDialog1 dialog


CDialog1::CDialog1(CWnd* pParent /*=NULL*/)
	: CDialog(CDialog1::IDD, pParent)
{
	m_bDraging = FALSE;
	//{{AFX_DATA_INIT(CDialog1)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CDialog1::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDialog1)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDialog1, CDialog)
	//{{AFX_MSG_MAP(CDialog1)
	//ON_WM_MOUSEACTIVATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDialog1 message handlers

int CDialog1::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
	//return MA_NOACTIVATE;
	return CDialog::OnMouseActivate(pDesktopWnd, nHitTest, message);
}

void CDialog1::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bDraging = TRUE;
	m_ptDrag = point;
	SetCapture();

	CString str;
	str.Format( _T("被点击时间 %s"),CTime::GetCurrentTime().Format( _T("%H:%M:%S") ) );
	SetDlgItemText( IDC_MOUSE,str );
	
	CDialog::OnLButtonDown(nFlags, point);
}

void CDialog1::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if( m_bDraging )
	{
		CWnd * pParent = this;//GetParent();
		if( pParent )
		{
			CRect rc;
			pParent->GetWindowRect( rc );
			GetParent()->ScreenToClient( rc );

			CRect rcWorkArea;
			SystemParametersInfo( SPI_GETWORKAREA,0,&rcWorkArea,0 );

			int nScreenWidth = GetSystemMetrics( SM_CXSCREEN );
			int nScreenHeight = GetSystemMetrics( SM_CYSCREEN );

			//任务栏在左边
			if( rcWorkArea.left > 0 )
			{
			}
			//任务栏在上边
			else if( rcWorkArea.top > 0 )
			{
			}
			//任务栏在下边
			else if( rcWorkArea.Height() < nScreenHeight )
			{
				CPoint ptCursor;
				GetCursorPos( &ptCursor );
				if( ptCursor.y < rcWorkArea.Height() )
					pParent->MoveWindow( rc.left + ( point.x - m_ptDrag.x ),rc.top + ( point.y - m_ptDrag.y ),rc.Width(),rc.Height() );
			}
			//任务栏在右边
			else if( rcWorkArea.Width() < nScreenWidth )
			{
			}
			CWnd * pWnd = GetParent();
//			if( pWnd )
//				pWnd->RedrawWindow();
		}
		//TRACE(_T("CFrameUI::OnMouseMove\r\n") );
	}
	
	CDialog::OnMouseMove(nFlags, point);
}

void CDialog1::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bDraging = FALSE;
	ReleaseCapture();
	
	CDialog::OnLButtonUp(nFlags, point);
}

zhllxt 2014-09-12
  • 打赏
  • 举报
回复
另外参考我以前发过的帖子,可以做出来一个完整的模拟键盘,这个帖子主要可以参考的地方是,如果全部用“画”的方式做一个模拟键盘:http://bbs.csdn.net/topics/390230336
zhllxt 2014-09-12
  • 打赏
  • 举报
回复
不知道你把模拟键盘做成单独的EXE是不是有什么特别要求,如果没有要求,可以直接将模拟键盘代码放在一个程序里就行。我以前摸索过,在自己的程序里没有问题,要求就是弹出模拟键盘时,模拟键盘上的按键一定要是画上去的,不能是标准Button,另外弹出模拟键盘时要指定SW_SHOWNOACTIVATE 相关代码如下:


// 模拟键盘功能的头文件
#if !defined(AFX_SKWINDOW_H__701E5898_513F_43BC_B04A_601D134EFA4C__INCLUDED_)
#define AFX_SKWINDOW_H__701E5898_513F_43BC_B04A_601D134EFA4C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// SKWindow.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CSKWindow window

class CSKWindow : public CWnd
{
// Construction
public:
CSKWindow();

// Attributes
public:
CRect m_rcA;
BOOL m_bAPressed;

// Operations
public:
BOOL Create( CWnd * pParent );

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSKWindow)
protected:
virtual void PostNcDestroy();
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CSKWindow();

// Generated message map functions
protected:
//{{AFX_MSG(CSKWindow)
afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SKWINDOW_H__701E5898_513F_43BC_B04A_601D134EFA4C__INCLUDED_)




// 模拟键盘的CPP文件
// SKWindow.cpp : implementation file
//

#include "stdafx.h"
#include "SK.h"
#include "SKWindow.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSKWindow

CSKWindow::CSKWindow()
{
m_rcA.SetRect( 3,3,24,24 );
m_bAPressed = FALSE;
}

CSKWindow::~CSKWindow()
{
}


BEGIN_MESSAGE_MAP(CSKWindow, CWnd)
//{{AFX_MSG_MAP(CSKWindow)
ON_WM_MOUSEACTIVATE()
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CSKWindow message handlers

BOOL CSKWindow::Create( CWnd * pParent )
{
BOOL bRet = FALSE;

bRet = CreateEx( 0,AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW,::LoadCursor(NULL,IDC_ARROW), HBRUSH(COLOR_WINDOW+1),NULL),
_T(""),WS_POPUP | WS_TABSTOP,CRect(1, 1, 256, 64),pParent,NULL,NULL);

return bRet;
}

int CSKWindow::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
return MA_NOACTIVATE;
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
}

void CSKWindow::OnPaint()
{
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
CRect rc;
GetClientRect( rc );
dc.FrameRect( rc,&CBrush( RGB( 0,0,255 ) ) );
dc.FrameRect( m_rcA,&CBrush( RGB( 0,255,255 ) ) );
dc.DrawText( _T("A"),m_rcA,DT_SINGLELINE | DT_CENTER | DT_VCENTER );
// Do not call CWnd::OnPaint() for painting messages
}

void CSKWindow::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this;
CWnd::PostNcDestroy();
}

void CSKWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if( m_rcA.PtInRect( point ) )
{
m_bAPressed = true;
}
CWnd::OnLButtonDown(nFlags, point);
}

void CSKWindow::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if( m_bAPressed )
{
if( m_rcA.PtInRect( point ) )
{
keybd_event( 'A',NULL,0,0 );
Sleep( 1 );
keybd_event( 'A',NULL,KEYEVENTF_KEYUP,0 );
}
}
m_bAPressed = false;
CWnd::OnLButtonUp(nFlags, point);
}




// 主对话框中点击按钮时触发的相应函数
void CSKDlg::OnBtnSk()
{
// TODO: Add your control notification handler code here
CSKWindow * pSKWindow = new CSKWindow;
pSKWindow->Create( this );
pSKWindow->ShowWindow( SW_SHOWNOACTIVATE );
pSKWindow->CenterWindow( this );
}


图片效果:


我当时把这个问题摸索出来以后就没有再细致的写代码了,就试了可以成功的输入“A”我就没做了,你可以参考一下。
凌乱哥 2014-09-12
  • 打赏
  • 举报
回复
引用 22 楼 zhllxt 的回复:
另外参考我以前发过的帖子,可以做出来一个完整的模拟键盘,这个帖子主要可以参考的地方是,如果全部用“画”的方式做一个模拟键盘:http://bbs.csdn.net/topics/390230336
哥们我想到一个问题,就是按你那样写出来的键盘CWnd,又是SW_SHOWNOACTIVATE的,那无法拖动啊。。。不知你有什么好主意没
Yofoo 2014-09-11
  • 打赏
  • 举报
回复
一个单独的exe,运行后是一个置顶的窗口,上面绘制了很多格子,用于模拟键盘 这个窗体弄成类似输入法的无焦点方式 也可以把窗体disable, 这样也会无法获取焦点, 有些输入法就是这么做的
hhhh63 2014-09-11
  • 打赏
  • 举报
回复
引用 10 楼 dingxz105090 的回复:
[quote=引用 1 楼 hhhh63 的回复:] 创建键盘窗口时加上 WS_EX_NOACTIVATE 样式,它就得不到焦点了。当然不能在键盘窗口中用按钮等控件,只能根据鼠标位置自己判断了。
妈蛋,VC6下不支持WS_EX_NOACTIVATE属性,然后我把整个工程移植到VS下,要改好多地方,瞬间不想搞了。。。[/quote] VC6应该有吧,用CreateEx方法 m_pMainWnd = new CWnd(); m_pMainWnd->CreateEx( WS_EX_NOACTIVATE, wndcls.lpszClassName, _T("test"), WS_OVERLAPPEDWINDOW, CRect(10, 10, 200, 200), NULL, NULL, NULL ); m_pMainWnd->ShowWindow( SW_SHOW );
schlafenhamster 2014-09-11
  • 打赏
  • 举报
回复
“点击编辑框” 才弹出 模拟键盘, 所以 gFocus 应该是 哪个 Edit 所在的窗口。 你 把 Edit 所在的窗口 的 句柄 传给 , 模拟键盘。
schlafenhamster 2014-09-11
  • 打赏
  • 举报
回复
gFocus = wnd;// 这是 ::GetForeGroundWindow(); 得来的 , 这时 还是你 的 程序。 ReleaseFocus();// 它 把 focus 还给 gFocus, 所以 这个 gfocus 一定要 通过 别的 方法 得到 用 ::GetForeGroundWindow(); 是不行的。
凌乱哥 2014-09-11
  • 打赏
  • 举报
回复
引用 9 楼 allenhiman 的回复:
你的程序体系 有没有后台运行的服务? 如果你有edit的那个程序给服务程序发个消息 让服务去启动键盘程序 就不会有这个问题了
那倒没有,不过可以试一下
凌乱哥 2014-09-11
  • 打赏
  • 举报
回复
引用 7 楼 schlafenhamster 的回复:
"刚起来的时候" 在PretranlateMessage中获取 gFocus 时把焦点就还回去.
你好,突然发现我的键盘程序里有你说的ReleaseFocus函数,而且做法完全跟你说的一样,但是我在PreTranslateMessage中不管是:

				gFocus = wnd;
				ReleaseFocus();
				AttachThreadInput(........);
还是:

				gFocus = wnd;
				AttachThreadInput(........);
				ReleaseFocus();
都无法在键盘启动时达到释放焦点的目的啊。。。 我随便新建了一个含Edit和Button的程序,响应了Edit的ON_EN_SETFOCUS消息:

void CTestFuckDlg::OnEnSetfocusEditInput()
{
	// TODO: Add your control notification handler code here
	ShellExecute(NULL,_T("open"),_T("OnscreenKeyboard.exe"),NULL,NULL,SW_SHOW);
}
要不我把我的键盘程序发给你看看?
凌乱哥 2014-09-11
  • 打赏
  • 举报
回复
引用 1 楼 hhhh63 的回复:
创建键盘窗口时加上 WS_EX_NOACTIVATE 样式,它就得不到焦点了。当然不能在键盘窗口中用按钮等控件,只能根据鼠标位置自己判断了。
妈蛋,VC6下不支持WS_EX_NOACTIVATE属性,然后我把整个工程移植到VS下,要改好多地方,瞬间不想搞了。。。
allenhiman 2014-09-11
  • 打赏
  • 举报
回复
你的程序体系 有没有后台运行的服务? 如果你有edit的那个程序给服务程序发个消息 让服务去启动键盘程序 就不会有这个问题了
kuankuan_qiao 2014-09-11
  • 打赏
  • 举报
回复
好早啊
加载更多回复(11)

15,980

社区成员

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

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