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

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

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

所以问题就是,如何改掉这个调出键盘后还得再点一下编辑框的问题?就好像是要让键盘永远无法得到焦点一样,因为我发现Win8的屏幕键盘出现以后一直是非焦点状态的,除非你鼠标左键一直按着它
...全文
654 31 打赏 收藏 转发到动态 举报
写回复
用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)
vb.net操作DataGridView控件的用法的集合,包括: 1. DataGridView当前的单元格属性取得、变更 2. DataGridView编辑属性 3. DataGridView最下面一列新追加行非表示 4. DataGridView判断当前选中行是否为新追加的行 5. DataGridView删除行可否设定 6. DataGridView行列不表示和删除 DataGridView控件用法合集(二) 7. DataGridView行列宽度高度设置为不能编辑 8. DataGridView行高列幅自动调整 9. DataGridView指定行列冻结 10. DataGridView列顺序变更可否设定 11. DataGridView行复数选择 12. DataGridView选择的行、列、单元格取得 DataGridView控件用法合集(三) 13. DataGridView指定单元格是否表示 14. DataGridView表头部单元格取得 15. DataGridView表头部单元格文字列设定 16. DataGridView选择的部分拷贝至剪贴板 17.DataGridView粘贴 18. DataGridView单元格上ToolTip表示设定(鼠标移动到相应单元格上时,弹出说明信息) DataGridView控件用法合集(四) 19. DataGridView中的ContextMenuStrip属性 20. DataGridView指定滚动框位置 21. DataGridView手动追加列 22. DataGridView全体分界线样式设置 23. DataGridView根据单元格属性更改显示内容 24. DataGridView新追加行的行高样式设置る 25. DataGridView新追加行单元格默认值设置 DataGridView中输入错误数据的处理(五) 26. DataGridView单元格数据错误标签表示 27. DataGridView单元格内输入值正确性判断 28. DataGridView单元格输入错误值事件的捕获 DataGridView控件用法合集(六) 29. DataGridView行排序(点击列表头自动排序的设置) 30. DataGridView自动行排序(新追加值也会自动排序) 31. DataGridView自动行排序禁止情况下的排序 32. DataGridView指定列指定排序 DataGridView控件用法合集(七) 33. DataGridView单元格样式设置 34. DataGridView文字表示位置的设定 35. DataGridView单元格内文字列换行 36. DataGridView单元格DBNull值表示的设定 37. DataGridView单元格样式格式化 38. DataGridView指定单元格颜色设定 39. DataGridView单元格文字字体设置 40. DataGridView根据单元格值设定单元格样式 DataGridView控件用法合集(八) 41. DataGridView设置单元格背景颜色 42. DataGridView行样式描画 43. DataGridView显示行号 44. DataGridView焦点所在单元格焦点框不显示的设定 DataGridView控件用法合集(九) 45. DataGridView中显示选择框CheckBox 46. DataGridView中显示下拉框ComboBox 47. DataGridView单击打开下拉框 48. DataGridView中显示按钮 49. DataGridView中显示链接 50. DataGridView中显示图像 DataGridView控件用法合集(十) 51. DataGridView编辑中单元格控件取得 52. DataGridView输入自动完成 53. DataGridView单元格编辑时键盘KEY事件取得 54. DataGridView下拉框(ComboBox)单元格编辑时事件取得 55. DataGridView下拉框(ComboBox)单元格允许文字输入设定 DataGridView控件用法合集(十一) 56. DataGridView根据值不同在另一列中显示相应图片 57. DataGridView中显示进度条(ProgressBar) 58. DataGridView中添加MaskedTextBox DataGridView控件用法合集(十二) 59. DataGridView中Enter键按下焦点移至旁边的单元格 60. DataGridView行集合化(Group)
UIDesigner(腾讯公司出品) 在软件设计阶段,交互设计师或者产品经理等常常需要使用一些工具(比如Visio、Axure RP、Flash或者OmniGraffle等)制作出静态稿或者原型来表达设计思想。这些工具是各有各的优势,当然也各有各的缺点啦。那么腾讯CDC是如何设计软件原型的呢?这里向大家介绍我们正在研发的原型设计利器UIDesigner。   首先,先让我们来体验一下UIDesigner制作出来的原型效果。这个原型是一个设置窗体,主要由按钮、复选框、分组框和文本框等控件构成,其中一些按钮还具有响应的动作(如打开另一个界面,关闭窗体等)。如图一所示,这是使用Firework制作出来的交互图。 图一、使用Firework制作出来的设计稿   这种交互图的特点是简单明了,能够表示出各种控件的基本属性(如文本、位置和选中状态等),但它只是一个静态的图片,不能真实表现出每个控件的响应动作,如仅看这张图,是不清楚点击代理服务器设置分组框上的“设置…”按钮会有什么响应的。   那再看看你若使用UIDesigner制作出来的效果:最终输出的是一个EXE可执行文件(见图二左上角),双击运行后就会出现一个与最终实现效果完全一致的窗体(见图二右)。另外,它还是一个具有响应动作的真实原型,例如你若点击了“设置…”按钮,那就会弹出一个新的窗体(见图三)。 图二、使用UIDesinger制作出来的原型 图三、点击“设置…”按钮后弹出的另一窗体   实际上,这个新弹出的窗体都是一个独立的原型,也是由UIDesigner制作出来的。由于它里面的控件同样可以设置下一步的响应动作,所以从总体上来看,众多原型就像一个树状结构,而其中的父节点就是图二中的设置窗体了。这种结构具有一个很大的好处:无论你完成了多个界面的原型,只需要它们之间有链接关系,最后输出的只是一个EXE可执行文件。这样,你可以很方便地与其它人员表达自己的设计思路,让沟通变得更加快捷。   接下来,我们看看这个原型是如何制作出来的。   第一步:建立空白窗体,调整它的大小、风格、标题和Icon 图四、使用UIDesigner制作原型—建立窗体   第二步:从工具箱中拖曳控件到窗体上,修改这些控件的属性(如Text等) 图五、使用UIDesigner制作原型—加入控件   由于UIDesigner具有自动对齐的功能,所以在拖动控件到窗体时就可以完成排版工作,不需要再逐个像素去调整。另外,不单单在加入控件到窗体时,在改变已存在于窗体内的控件的位置或者大小时,自动对齐功能一样会生效。这样,设计者在调整控件大小或者位置时(包括控件与控件,控件与窗体边缘等的距离等情况),工作变得很简单。 图六、使用UIDesigner制作原型—自动对齐功能   第三步:几分钟后,所有的控件都放到窗体并设置好属性了,如下图。 图七、使用UIDesigner制作原型—整体界面效果   此时,设计者就可以使用软件的导出图片或者导出原型功能分享你的设计成果了。当然,现在这种效果还只是一个没有响应动作效果的原型。接下来,我们再给“设置…”按钮加入响应动作。首先,选中“设置…”按钮,然后点击工具栏的“响应”按钮,你将会看到如图八的响应设置窗口。此时,你可以选择打开窗体、打开网页、弹出对话框、修改属性值和关闭本身窗体等五种效果,这里我们选择“打开窗体”,然后在弹出的对话框里指向弹出窗体的文件。最后,点击“完成”按钮即可。 图八、使用UIDesigner制作原型—设置控件的响应动作   到此为止,你就完成了一个与最终实现效果完全一致的高保真原型了。产品经理和开发人员等若想了解你的设计思想就不需要看着长长几页的说明文档了,而只需要运行你输出的原型文件,就可以对你的设计思路一目了然。   UIDesigner除了能让使用者能够快速地搭建起软件界面的高保真原型外,还提供了项目管理,让使用者能够方便地管理工程文件;提供了图片库和模板库功能,让使用者可以方便地重用以前的设计资源;提供了32个Windows客户端软件常用控件,满足使用者的设计需求;提供了多个属性设置入口,分别实现最常用属性设置、一般属性设置和高级属性设置功能。当然,UIDesigner不是专用来设计QQ的,其它的Windows客户端产品都在它的工作范围之内。总的来说呢,使用UIDesigner来制作原型是很高效的,而制作出来的原型也能够实现设计师、产品经理和程序开发工程师三者间的快速沟通,减少不必要的工作内耗。 ------------------------------------------------------------------ GUI_Design_Studio_3.5.94.0 在2008年,这款软件的作者从1,322位付费用户那获得了162,302美元的收入(其中仅12月份就有39,000美元),这令人鼓舞地证明了只要是提供真正价值的服务和软件,就能够创造很好的收入,即使在经济萧条的寒冬里。 GUI Design Studio是一款图形用户界面设计工具,您能用它在不需要编写任何代码或脚本的情况下快速地创建演示原型。使用标准元素绘制个人化的屏幕、窗口以及控件;将它们整合以展示操作工作流然后运行模拟程序测试您的设计。 当您需要绘制一款应用程序的外观或显示怎样将程序的各个部分连接起来时,您就可以使用GUI Design Studio来实现,如: 将产品创意文档化 制作项目提案 需求记录 创建屏幕图样 为开发人员制作详细的规格 为现有产品提出加强方案 以及更多其它用途 为用户以及股东甚至您自己制作展示文件以: 验证设计 找出替代项 评估多个使用场景 系统需求 Microsoft Windows Vista/XP/NT/2000 至少15MB的硬盘空间 推荐不少于256MB的内存 工程 将您的工作组织放到工程里。 每个工程都拥有它自己的文件夹结构。 可连接您计算机或网络上任何地方的其它库工程。 可连接到您计算机或网络上任何地方使您能够方便地获取图片以及其它文件。 创建您想要的并独立于所有工程的个人化设计文件。 创建能重复使用的设计库以及工程之间的一致性。 将图片直接从剪贴板中粘贴到工程文件夹的文件中。 屏幕设计程序 可同时打开多个设计文档并能使用分页界面在文档间快速切换。 可使用标准Windows元素创建图形用户界面(GUI)屏幕,包括框架窗口、会话、菜单、工具栏、标签、按钮、复选框、单选按钮、滚动条、滑动调节框、微调框、组合框、树列表、列表框、编辑框以及静态文本等。 通过现有元素或其它自定义控件创建自定义控制组件。 在其它设计中创建将要使用的控件设计。 以常用的文件格式添加图标与图片。 从能够显示您将获得什么的控件面板中进行拖放操作。 属性编辑程序使您能将每个元素进行自定义。 元素的自动生成功能。 您能在任何地方放置任何元素。 Edge snapping能通过“点击”对屏幕元素进行统一记录。 设计网格向您提供了简单的制作具有一致性设计布局的方法。 只需单键点击就能排列元素组。 均衡地隔开元素组。 调整元素大小以适应其它元素或测量一组其它元素。 聚焦缩小以查看细节设计或聚焦放大以浏览设计概况。使用工具栏按键或键盘或鼠标的滑动缩小放大功能聚焦增量。 使用鼠标的滚动以及滚轮功能快速浏览设计的概况。 剪切、复制与粘贴。 使用可选的canvas向导显示可用的屏幕空间。 通过文本框与书签对您的设计进行注释。 为每个设计添加说明。 选择色彩主题以避免实际功能窗口的混淆。 图标 为图标面板提供快速的访问方式。 工程间可共享常用图标。 工程也能拥有它们独享的图标集。 使用将来在实际产品开发中可能用到的标准ICO文件。 包含的Icon Express编辑程序支持16色、256色以及最大尺寸为127 x 127的真彩图标。 如果愿意同样能整合任意其它的图标编辑应用程序。 展示与原型 在可导航元素(如按键与窗口)之间创建连接以显示控制流程。 为图象添加覆盖保护以及添加其它元素以创建可导航的热点。 支持形式化与非模态的窗口并支持显示、隐藏或微调窗口,以及窗口替换以实现切换效果。 锚点使您能对窗口进行准确定位。 能立即在模拟程序中测试或展示您的设计。 添加消息框以描述可能在真实应用程序中出现的功能。 可创建多种场景,如正常条件下的场景与多个出错场景。 选择要激活的场景或让模拟程序为您选择。 更改有效的屏幕分辨率以查看您的设计如何适应不同的屏幕大小。 在没有进行脚本或代码编写的情况下,所有操作都是以图形模式完成。 ------------------------------------------------------------------ Balsamiq_Mockups_1.8.4 1. 首先安装 AdobeAIRInstaller.exe 2. 安装主程序 MockupsForDesktop.air 3. 使用 keygen 进行注册 在Balsamiq Mockups中绘制界面原型,就像在纸张和白板上手工绘画一样方便快速,而且不用担心出错,因为你完全可以进行回复/重做。在Balsamiq Mockups中设计原型比在纸张和白板可有趣多了! 丰富的控件支持 Balsamiq Mockups预先提供了丰富的控件,如浏览器窗口、媒体播放器组件、圆形图表等,让你信手拈来! 丰富的控件 方便的属性设置 当你选择一个控件时,会立刻出现该控件的属性选项,你可以随时编辑修改属性。 属性设定 无限的恢复/重做,不用担心出错,你可以无限制的进行回复和重做。 开放,可移植的数据 Balsamiq Mockups所生成的数据是易于阅读的XML格式数据,你可以进行方便的移植和重用集成。 开放的数据 多种方式的集成应用,你可以将Balsamiq Mockups集成倒Confluence, Jira, XWiki中. 集成应用 Balsamiq Mockups是一款免费的带有手绘风格的原型设计软件,可以帮助你设计桌面应用软件,Web 2.0 站点, RIA富网络应用程序, Web站点和Web应用软件。 功能和亮点: 操作方面:拖拽,控件分组,甚至元素之间的对齐都做得很到位; 预制了六十多个界面元素,从简单的输入框,下拉框,到经常用得到的导航条,日历,表格,到复杂的Tag Cloud,Cover Flow, 地图,WYSWYG的格式工具栏等,有了这些不用从头画起,其实比用白板都快; 界面元素的修改很简单,比如导航条的几个标签页的label,就是用逗号分隔的文字,下拉框的选项就是分行的文字; 使用xml语言来记录和保存界面元素和布局,从而使其能够快速的导入到你所需的任何一个项目中,或其他工具中。 可以将设计导出成PNG格式的图片; 随着使用的熟练,快捷键便派上用场,超过一半的元素均有快捷方式,这更有助于原型的快速构造,几乎几分钟便可实现一个满意的而复杂的原型设计; 跨平台,Balsamiq Mokups是用Flex和Air实现的,所以在Mac OS, Linux和Windows下都能使用; 不仅仅有桌面版本,还有能集成在Confluence,JIRA,和XWiki中的版本,使得异地在线协作更方便有效。 可以用命令行进行导出操作,这样就能让我写个脚本,从svn里checkout某个目录下的所有设计文件后,导出图片,打包后用邮件发到项目经理,工程师甚至客户那; 跨平台,Balsamiq Mokups是用Flex和Air实现的,所以在Mac OS, Linux和Windows下都能使用;不仅仅有桌面版本,还有能集成在Confluence,JIRA,和XWiki中的版本,使得异地在线协作更方便有效;据作者说,现在这款软件的设计就是用它自己来设计的,经典的“吃自己的狗粮”,这也让我对其更有信心,因为它是开发者为开发者写的软件。 还有值得一提的是Balsamiq Mokups的在GetSatisfaction上的用户支持和服务,作者Peldi对问题报告,新需求的回应很积极和及时。而且根据这个讨论上看,到月底就会有一个专门用来分享界面控件设计的社区网站了,很期待。 再要说的一点是这款软件是要付费的,79美元(也可以免费,具体如何免费,请看网站上的说明),相对于它能节省下来的时间和提高的效率,是很值得的。Peldi说在2008年,这款软件就从1,322位付费用户那获得了162,302美元的收入(其中仅12月份就有39,000美元),这令人鼓舞地证明了只要是提供真正价值的服务和软件,就能够创造很好的收入,即使在经济萧条的寒冬里。

15,979

社区成员

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

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