用服务启动界面程序

用服务启动界面程序
用服务启动界面程序

#ifndef _WIN32_WINNT

#define _WIN32_WINNT 0x0501

#endif

#ifndef WINVER

#define WINVER 0x0501

#endif

#include

#include

#include

#pragma comment(lib, "WtsApi32.lib")

// LaunchWithActiceSession() 用于在Service中把一个程序以当前活动会话的用户权限运行起来

// szExeName 可执行程序全路径,同CreateProcess()第一个参数

// szCmdLine 执行程序的命令行,同CreateProcess()第二个参数

// szCurrentDirectory 程序运行的当前目录,同CreateProcess()第三个参数

// bShowWindow 该程序是否显示界面

// bWait 是否等待该程序退出

// lpHandle 此参数可以返回进程的Handle

DWORD LaunchWithActiceSession( IN LPCTSTR szExeName, IN LPTSTR szCmdLine=NULL, IN LPCTSTR szCurrentDirectory=NULL, IN BOOL bShowWindow=TRUE, IN BOOL bWait=FALSE, OUT HANDLE *lpHandle=NULL );

DWORD GetLogonSID( IN HANDLE hToken, OUT PSID *ppsid )

{

DWORD dwResult = 0;

DWORD dwIndex = 0;

DWORD dwLength = 0;

BOOL bFound = 0;

PTOKEN_GROUPS ptg = NULL;

do

{

if ( NULL == ppsid )

{

dwResult = FormatError(ERROR_INVALID_PARAMETER); break;

}

if ( !::GetTokenInformation( hToken, TokenGroups, (LPVOID)ptg, 0, &dwLength ) )

{

dwResult = ::GetLastError();

if ( ERROR_INSUFFICIENT_BUFFER != dwResult )

{

FormatError(dwResult); break;

}

dwResult = 0;

ptg = (PTOKEN_GROUPS)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength );

if ( ptg == NULL )

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

}

if ( !::GetTokenInformation( hToken, TokenGroups, (LPVOID)ptg, dwLength, &dwLength ) )

{

dwResult = FormatError(::GetLastError()); break;

}

for ( dwIndex=0; dwIndexGroupCount; dwIndex++ )

{

if ( (ptg->Groups[dwIndex].Attributes&SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID )

{

bFound = TRUE;

dwLength = ::GetLengthSid( ptg->Groups[dwIndex].Sid );

*ppsid = (PSID)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength );

if ( *ppsid == NULL )

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

if ( !::CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid) )

{

dwResult = FormatError(::GetLastError());

::HeapFree( ::GetProcessHeap(), 0, (LPVOID)*ppsid );

break;

}

break;

}

}

if ( dwResult ) break;

if ( !bFound )

{

dwResult = FormatError(ERROR_FILE_NOT_FOUND); break;

}

} while (0);

if ( ptg )

{

::HeapFree( ::GetProcessHeap(), 0, (LPVOID)ptg );

}

return dwResult;

}

#define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \ DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \

DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \

DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)

#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \ WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \

WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \

WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \

STANDARD_RIGHTS_REQUIRED)

#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)

DWORD AddAceToWindowStation(HWINSTA hwinsta, PSID psid)

{

DWORD dwResult = 0;

ACCESS_ALLOWED_ACE *pace = NULL;

ACL_SIZE_INFORMATION aclSizeInfo;

BOOL bDaclExist;

BOOL bDaclPresent;

DWORD dwNewAclSize;

DWORD dwSidSize = 0;

DWORD dwSdSizeNeeded;

PACL pacl;

PACL pNewAcl = NULL;

PSECURITY_DESCRIPTOR psd = NULL;

PSECURITY_DESCRIPTOR psdNew = NULL;

PVOID pTempAce;

SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;

unsigned int i;

do

{

if ( !::GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded) )

{

dwResult = ::GetLastError();

if ( dwResult != ERROR_INSUFFICIENT_BUFFER )

{

FormatError(dwResult); break;

}

dwResult = 0;

psd = (PSECURITY_DESCRIPTOR)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded );

if (psd == NULL)

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

psdNew = (PSECURITY_DESCRIPTOR)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded );

if (psdNew == NULL)

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

dwSidSize = dwSdSizeNeeded;

if ( !::GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded ) )

{

dwResult = FormatError(::GetLastError()); break;

}

}

if ( !::InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION ) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist ) )

{

dwResult = FormatError(::GetLastError()); break;

}

ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));

aclSizeInfo.AclBytesInUse = sizeof(ACL);

if ( pacl != NULL )

{

if ( !::GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation ) )

{

dwResult = FormatError(::GetLastError()); break;

}

}

dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*::GetLengthSid(psid)) - (2*sizeof(DWORD));

pNewAcl = (PACL)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize );

if ( pNewAcl == NULL )

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

if ( !::InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION) )

{

dwResult = FormatError(::GetLastError()); break;

}

if (bDaclPresent)

{

if (aclSizeInfo.AceCount)

{

for (i=0; i < aclSizeInfo.AceCount; i++)

{

if ( !::GetAce(pacl, i, &pTempAce) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) )

{

dwResult = FormatError(::GetLastError()); break;

}

}

if ( dwResult ) break;

}

}

pace = (ACCESS_ALLOWED_ACE *)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE) + ::GetLengthSid(psid) - sizeof(DWORD));

if ( pace == NULL )

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;

pace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;

pace->Header.AceSize = LOWORD(sizeof(ACCESS_ALLOWED_ACE) + ::GetLengthSid(psid) - sizeof(DWORD));

pace->Mask = GENERIC_ACCESS;

if ( !::CopySid(::GetLengthSid(psid), &pace->SidStart, psid) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize ) )

{

dwResult = FormatError(::GetLastError()); break;

}

pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;

pace->Mask = WINSTA_ALL;

if ( !::AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::SetUserObjectSecurity(hwinsta, &si, psdNew) )

{

dwResult = FormatError(::GetLastError()); break;

}

} while (0);

if (pace != NULL)

{

::HeapFree(::GetProcessHeap(), 0, (LPVOID)pace);

}

if (pNewAcl != NULL)

{

::HeapFree(::GetProcessHeap(), 0, (LPVOID)pNewAcl);

}

if (psd != NULL)

{

::HeapFree(::GetProcessHeap(), 0, (LPVOID)psd);

}

if (psdNew != NULL)

{

::HeapFree(::GetProcessHeap(), 0, (LPVOID)psdNew);

}

return dwResult;

}

DWORD AddAceToDesktop(HDESK hdesk, PSID psid)

{

DWORD dwResult = 0;

ACL_SIZE_INFORMATION aclSizeInfo;

BOOL bDaclExist;

BOOL bDaclPresent;

BOOL bSuccess = FALSE;

DWORD dwNewAclSize;

DWORD dwSidSize = 0;

DWORD dwSdSizeNeeded;

PACL pacl;

PACL pNewAcl = NULL;

PSECURITY_DESCRIPTOR psd = NULL;

PSECURITY_DESCRIPTOR psdNew = NULL;

PVOID pTempAce;

SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;

unsigned int i;

do

{

if ( !::GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded) )

{

dwResult = ::GetLastError();

if ( dwResult != ERROR_INSUFFICIENT_BUFFER )

{

FormatError(dwResult); break;

}

dwResult = 0;

psd = (PSECURITY_DESCRIPTOR)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded );

if (psd == NULL)

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

psdNew = (PSECURITY_DESCRIPTOR)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded );

if (psdNew == NULL)

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

dwSidSize = dwSdSizeNeeded;

if ( !::GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded ) )

{

dwResult = FormatError(::GetLastError()); break;

}

}

if ( !::InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) )

{

dwResult = FormatError(::GetLastError()); break;

}

ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));

aclSizeInfo.AclBytesInUse = sizeof(ACL);

if (pacl != NULL)

{

if ( !::GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation ) )

{

dwResult = FormatError(::GetLastError()); break;

}

}

dwNewAclSize = aclSizeInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + ::GetLengthSid(psid) - sizeof(DWORD);

pNewAcl = (PACL)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize );

if (pNewAcl == NULL)

{

dwResult = FormatError(ERROR_NOT_ENOUGH_MEMORY); break;

}

if ( !::InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION) )

{

dwResult = FormatError(::GetLastError()); break;

}

if (bDaclPresent)

{

if (aclSizeInfo.AceCount)

{

for (i=0; i < aclSizeInfo.AceCount; i++)

{

if ( !::GetAce(pacl, i, &pTempAce) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) )

{

dwResult = FormatError(::GetLastError()); break;

}

}

if ( dwResult ) break;

}

}

if ( !::AddAccessAllowedAce( pNewAcl, ACL_REVISION, DESKTOP_ALL, psid) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE ) )

{

dwResult = FormatError(::GetLastError()); break;

}

if ( !::SetUserObjectSecurity(hdesk, &si, psdNew) )

{

dwResult = FormatError(::GetLastError()); break;

}

} while (0);

if (pNewAcl != NULL)

{

::HeapFree(::GetProcessHeap(), 0, (LPVOID)pNewAcl);

}

if (psd != NULL)

{

::HeapFree(::GetProcessHeap(), 0, (LPVOID)psd);

}

if (psdNew != NULL)

{

::HeapFree(::GetProcessHeap(), 0, (LPVOID)psdNew);

}

return dwResult;

}

void FreeLogonSID( PSID *ppsid )

{

::HeapFree( ::GetProcessHeap(), 0, (LPVOID)*ppsid );

}

DWORD GetSessionUserName(DWORD dwSessionId, OUT LPTSTR lpszUserName ) {

DWORD dwResult = 0;

LPTSTR pBuffer = NULL;

DWORD dwBufferLen = 0;

do

{

if ( !::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen) )

{

dwResult = FormatError(::GetLastError()); break;

}

_tcscpy( lpszUserName, pBuffer );

} while (0);

if ( pBuffer )

{

::WTSFreeMemory(pBuffer);

}

return dwResult;

}

DWORD GetSessionDomain(DWORD dwSessionId, OUT LPTSTR lpszDomainName )

{

DWORD dwResult = 0;

LPTSTR pBuffer = NULL;

DWORD dwBufferLen = 0;

do

{

if ( !::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSDomainName, &pBuffer, &dwBufferLen) )

{

dwResult = FormatError(::GetLastError()); break;

}

_tcscpy( lpszDomainName, pBuffer );

} while (0);

if ( pBuffer )

{

::WTSFreeMemory(pBuffer);

}

return dwResult;

}

DWORD LaunchWithActiceSession( IN LPCTSTR szExeName, IN LPTSTR szCmdLine/*=NULL*/, IN LPCTSTR szCurrentDirectory/*=NULL*/, IN BOOL bShowWindow/*=TRUE*/, IN BOOL bWait/*=FALSE*/, OUT HANDLE *lpHandle/*=NULL*/ )

{

DWORD dwResult = 0;

DWORD dwActiveSessionId = 0;

HANDLE hActiveSessionToken = INVALID_HANDLE_VALUE;

DWORD dwExitCode = ERROR_SUCCESS;

PSID pSid = NULL;

HWINSTA hWinstaSave = NULL;

HWINSTA hWinsta = NULL;

HDESK hDesk = NULL;

PROCESS_INFORMATION pi;

STARTUPINFO si;

do

{

si.dwFlags = STARTF_USESHOWWINDOW;

if ( bShowWindow )

{

si.wShowWindow = SW_SHOWDEFAULT;

}

else

{

si.wShowWindow = SW_HIDE;

}

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

dwActiveSessionId = ::WTSGetActiveConsoleSessionId();

if ( 0xFFFFFFFF == dwActiveSessionId )

{

dwResult = FormatError( ::GetLastError() ); break;

}

if ( !::WTSQueryUserToken( dwActiveSessionId, &hActiveSessionToken ) )

{

FormatError( ::GetLastError() );

// WTSGetActiveConsoleSessionId() 取出来的会话ID不可用,枚举所有会话

WTS_SESSION_INFO *lpSessionInfo = NULL;

DWORD dwSessionInfoCount = 0;

DWORD dwSessionIDThis = -1;

TCHAR szDomain[256] = {0};

TCHAR szUserName[256] = {0};

do

{

if ( !::WTSEnumerateSessions( WTS_CURRENT_SERVER_HANDLE, 0, 1, &lpSessionInfo, &dwSessionInfoCount) )

{

dwResult = FormatError( ::GetLastError() ); break;

}

if ( dwSessionInfoCount == 0 )

{

dwResult = FormatError( ERROR_FILE_NOT_FOUND ); break; // 无活动会话

}

for ( DWORD i=0; i

{

RtlZeroMemory( szDomain, sizeof(szDomain) );

RtlZeroMemory( szUserName, sizeof(szUserName) );

GetSessionDomain( lpSessionInfo[i].SessionId, szDomain );

GetSessionUserName( lpSessionInfo[i].SessionId, szUserName );

}

for ( i=0; i

{

if ( lpSessionInfo[i].State == WTSActive || lpSessionInfo[i].State == WTSDisconnected )

{

if ( lpSessionInfo[i].SessionId != dwActiveSessionId )

{

dwSessionIDThis = lpSessionInfo[i].SessionId; break;

}

}

}

if ( dwSessionIDThis == -1 )

{

dwResult = FormatError( ERROR_FILE_NOT_FOUND ); break; // 无活动会话

}

} while (0);

if ( lpSessionInfo )

{

::WTSFreeMemory(lpSessionInfo);

}

if ( dwResult ) break;

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

dwActiveSessionId = dwSessionIDThis;

//MyDbgPrint( _T("Set dwActiveSessionId = %lu"), dwActiveSessionId );

if ( !::WTSQueryUserToken( dwActiveSessionId, &hActiveSessionToken ) )

{

// 当会话是远程桌面连接时(会话State==WTSDisconnected),不能获取令牌,总是返回122

// 参考https://www.360docs.net/doc/6c10835510.html,/kb/920754/

dwResult = FormatError( ::GetLastError() ); break;

}

}

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

hWinstaSave = ::GetProcessWindowStation();

if ( NULL == hWinstaSave )

{

dwResult = FormatError( ::GetLastError() ); break;

}

hWinsta = ::OpenWindowStation( _T("winsta0"), FALSE, READ_CONTROL|WRITE_DAC );

if ( NULL == hWinsta )

{

dwResult = FormatError( ::GetLastError() ); break;

}

if ( !::SetProcessWindowStation(hWinsta) )

{

dwResult = FormatError( ::GetLastError() ); break;

}

hDesk = ::OpenDesktop( _T("default"), 0, FALSE, READ_CONTROL|WRITE_DAC|DESKTOP_WRITEOBJECTS|DESKTOP_READOBJECTS );

if ( !::SetProcessWindowStation(hWinstaSave) )

{

dwResult = FormatError( ::GetLastError() ); break;

}

if ( NULL == hDesk )

{

dwResult = FormatError( ERROR_NOT_ENOUGH_MEMORY ); break;

}

dwResult = GetLogonSID(hActiveSessionToken, &pSid);

if ( dwResult )

{

FormatError( dwResult ); break;

}

dwResult = AddAceToWindowStation(hWinsta, pSid);

if ( dwResult )

{

FormatError( dwResult ); break;

}

dwResult = AddAceToDesktop(hDesk, pSid);

if ( dwResult )

FormatError( dwResult ); break;

}

if ( !::ImpersonateLoggedOnUser(hActiveSessionToken) )

{

dwResult = FormatError( ::GetLastError() ); break;

}

ZeroMemory(&si, sizeof(STARTUPINFO));

si.cb= sizeof(STARTUPINFO);

si.lpDesktop = TEXT("winsta0\\default");

if( !::CreateProcessAsUser(hActiveSessionToken,szExeName,szCmdLine,NULL,NULL,FALSE,NO RMAL_PRIORITY_CLASS,NULL,szCurrentDirectory,&si,&pi) )

{

dwResult = FormatError( ::GetLastError() );

}

::RevertToSelf();

if ( dwResult ) break;

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

if ( lpHandle )

{

*lpHandle = pi.hProcess;

}

if ( bWait )

{

dwExitCode = ::WaitForSingleObject( pi.hProcess, INFINITE );

if (WAIT_OBJECT_0 == dwExitCode)

{

if ( !::GetExitCodeProcess( pi.hProcess, &dwExitCode ) )

{

dwExitCode = FormatError( ::GetLastError() );

}

else

{

dwExitCode = ERROR_SUCCESS;

}

}

}

} while(0);

if ( hWinstaSave != NULL )

{

::SetProcessWindowStation( hWinstaSave );

}

{

FreeLogonSID(&pSid);

}

if (hWinsta)

{

::CloseWindowStation(hWinsta);

}

if (hDesk)

{

::CloseDesktop(hDesk);

}

if ( INVALID_HANDLE_VALUE != hActiveSessionToken ) {

::CloseHandle(hActiveSessionToken);

}

return dwResult;

}

系统界面设计规范

B/S 系统界面设计规范 1.引言 界面美观、操作易用性、维护成本低是评价B/S系统的关键。本规范参考了一些成熟产品科学的开发方法,将开发过程中的方式、规则等强行的约束。希望藉此来提高用户操作感受,提升B/S产品的质量。 1.1. 编写目的 广义的界面概念包含了除页面布局设计之外,交互性的设计,及人体工程学方面的研究。本规范制订的依据从广义概念出发,总结以往项目的成败经验,目的是从整体上提升公司B/S类产品的质量、开发效率。从以技术为中心发展为以客户为中心,将类似项目成功的经验继承和积累下来,将B/S系统与C/S系统开发过程上的区别降低到仅显示控制的极小的层面。新的开发方式强调分层,规范出界面设计人员做什么,服务器编程人员做什么,这样就把页面和控制代码两个层面清晰的分开。 1.2. 背景 B/S模式系统以其易部署、易扩展、能够高度集成各种技术的特点,在公司产品线中占越来越大的比重,.Net、J2ee等技术的发展更是将B/S系统的开发和桌面应用程序开发的工程方法统一起来,突出服务器端技术,这些变革要求界面设计人员和服务器端编程人员可以应用更加科学的方法合作,团队的合作方式甚至决定了一个系统开发的成败。目前公司较多的服务器端编程人员仍然处于“后ASP 时代”的开发方式,表现为前台页面仍然与服务器代码高度的关联,带来的后果是重复建设、高昂的维护成本或失去控制的项目,没有充分的发挥出集成开发工具的优势。在以往的开发方式下界面设计侧重在静态页面的建设上,每个页面作为一个独立的模块来处理,在页面交互中则是程序员根据自己的习惯来控制,程序对个人的编程风格的依赖很强,这些在以往开发WEB站点的方式扩展到B/S系统有时是不正确的,甚至是背道而弛的,当然也不利于规模化的团队合作。 1.3. 定义 术语定义: 效果图:由界面设计人员设计的页面效果图,综合了概要设计的业务需要和整个站点的风格,它规定了页面布局上的每个细节。 容器:即HTML 标记的嵌套结构,如在表格->行->单元格内放置图片,那么可以认为单元格是放置图片的容器。 样式表:即级联式样式表CSS,它是W3C机构在HTML标记语言上扩展的格式语言。 非标准交互控件:是通过标准控件组合、扩展等方法以提高特定业务执行效率而进行封装的控件,或概括为用户根据以往的操作经验不能够直接领会出操作方式的交互控件。 2. 界面设计规范细则 总体目标 以规范作为基本原则,在此框架内进行合理的扩展和变化,将站点内的每个模块服从于整个站点,模块页面与“高内聚”的控制代码紧密的结合在一起,同时对应于应用程序基于系统的架构分析。 2.1. 通用原则 1 界面色彩要求:计算机屏幕的发光成像和普通视觉成像有很大的不同,应该注意这种

服务操作流程及规范

前台散客接待服务流程与规范 (1)服务程序 欢迎客人实名制入住登记收取押金 送客进房资料存档 (2)服务规范 1.欢迎客人 ①客人进店后,接待员面带微笑地向客人致意问候,获 悉客人要住店后,应询问客人有无预订。 ②若客人有预订,询问客人姓名,找出预订单;复述客 人的预订房间、数量、离店时间并与客人核实有无变更。 ③若客人没有预订,问清客人所需房间类型及有无特殊 要求,对于第一次光临招待所的客人,要主动将房价表双手呈递给客人,按由高到低的原则向客人做简单的介绍和推销。客人确认房间类型后,迅速在电脑上查找,根据分房原则,将房号告诉客人并征得客人同意。 2.实名制入住登记 ①接待员请客人出示有效证件,检查证件照片和客人本 人是否相符;检查证件印章、证件期限是否有效。 ②证件检查完毕后,请客人填写登记表,同时在电脑中 选出客人要求的房型并将房号在《房间状况表》上标明该房已出租。

③审核客人是否已按入住登记表上的列项填写清楚、完 整。 ④准备好房卡,向客人介绍房间情况、招待所设施及招 待所的各种规定。 ⑤对于预订的客人,要检查是否有为其代收的信件或物 品,如有应及时转交给客人并办理相关手续。 3.收取押金 ①接待员询问客人押金支付方式并协助前台收银员收取 押金。 ②接待员在入住登记表上写清房价、押金支付方式及数目并签字。 4.送客进房 ①入住手续办理完毕后,接待员询问客人是否需要其他帮助。 ②若客人需要搬行李,则将房卡交给行李生,由其引领客人进房间。 ③若客人不需要帮助,用双手将房卡交给客人并告诉其电梯方位。 ④客人离开时,与客人道别并祝客人入住愉快。 5.资料存档 ①接待完毕后,接待员按照登记表上填写的内容,准确 地将信息输入电脑。 ②将登记表放入客人入住档案中,以便随时查询。

界面设计的基本步骤

界面设计的基本步骤 近年来,UI设计师成为一个火爆的职业,各大IT企业人才需求迫切,但想成功进入UI行业成为一个逼格高薪水高的UI设计师,你需要有丰富的UI设计方面技能,除了掌握软件,你还需要有实战型的设计技能,这样才能成为企业需要的高技术水平的UI设计师。 UI设计涉及的范围比较广泛,它是包括网站、移动端界面设计,网页设计,交互设计等多个方面,UI设计是对软件的人机交互、操作逻辑、界面美观度的整体设计。那么界面设计的基本步骤有哪些呢? 1、用户调研:拟定需求,综合分析得到产品使用情况的一个大致概貌。 2、产品分析:根据产品的复杂性、难易程度等,详细分解任务动作,进行合理分工,确定适合于用户的交互方式; 3、产品定位:在了解了用户,了解了相关产品后,针对产品做出的定位才会更加明确。 4、环境分析:确定系统的硬、软件支持环境及接口,向用户提供各类文档要求等; 5、屏幕显示和布局设计:制定屏幕显示信息的内容和界面显示的次序,然后进行屏幕总体布局和显示结构设计。 6、帮助和出错信息设计:决定和安排帮助信息和出错信息的内容,组织查询方法,井进行出错信息、帮助信息的显示格式设计; 7、确定界面:根据用户的自身特性.以及产品分析和定位,确定使用的开发环境和产品布局得出产品的界面设计结构图,确立产品界面原型: 8、视觉设计包括为吸引用户的注意所进行的增强显示的设计,例如,采取运动,改变形状、大小、颜色、亮度、环境等特征(如加线,加框、前景和背景设计等),9、原型试用:在经过初步系统需求分析后,开发出一个满足系统摹本要求的、简单的、可运行系统给用户试用,让用户进行评价提出改进意见,进一步完善系统的需求规格和系统设计;

微信小程序设计规范

概要 微信小程序设计的基本原则是微信设计中心针对在微信内上线的小程序页面总结的设计指南及建议。以下设计原则都是基于对用户的尊重的基础上的,旨在微信生态内建立友好、高效、一致的用户体验的同时,最大程度顺应和支持各业务需求设计,实现用户与程序的共赢。 一、友好礼貌 为了避免用户在微信中使用小程序服务时,注意力被周围复杂环境干扰,小程序在设计时应该注意减少无关的设计元素对用户目标的干扰,礼貌地向用户展示程序侧提供的服务,友好地引导用户进行操作。 1. 重点突出 每个页面都应有明确的重点,以便于用户每进入一个新页面的时候都能快速地理解页面内容,在确定了重点的前提下,应尽量避免页面上出现其他干扰项影响用户的决策和操作。 反例示意 此页面的主题是查询,却添加了诸多与查询不相关的业务入口,与用户的预期不符,易造成用户的迷失。

纠正示意 去掉任何与用户目标不相关的内容,明确页面主题,在技术和页面控件允许的前提下提供有助于用户目标的帮助内容,比如最近搜索词,常用搜索词等。 反例示意 操作没有主次,让用户无从选择

纠正示意 首先要避免并列过多操作让用户选额,在不得不并列多个操作时,需区分操作主次,减轻用户的选择难度。

2. 流程明确 为了让用户顺畅地使用页面,在用户进行某一个操作流程时,应避免出现用户目标流程之外的内容而打断用户。 反例示意 用户本打算进行搜索,在进入页面时却被突如其来的抽奖弹窗所打断;对于抽奖没有兴趣的用户是非常不友好的干扰,平添一份对开发团队的恼怒;而即便有部分用户确实被“诱人”的抽奖活动所吸引,离开主流程去抽奖之后可能就遗忘了原本的目标,进而失去了对产品真正价值的利用和认识。 二、清晰明确 作为一个负责任的开发者,一旦用户进入我们的小程序页面,就有责任和义务清晰明确地告知用户身在何处、又可以往何处去,确保用户在页面中游刃有余地穿梭而不迷路,这样才能为用户提供安全的愉悦的使用体验。

小程序服务合同

小程序服务合同甲方:乙方:地址:省市县(区) 地址:电话:电话:传真:传真:一、甲方向乙方购买服务项目如下:

二、服务约定 1、用户(甲方)与授权服务商(乙方)本着平等自愿的原则,就乙方为甲方提供小程序开发服务相关事宜签订本合同,供双方遵守。 2、双方签约并按约定合同款项支付到乙方账户上后,乙方对小程序开发的合法性、规范性、以及甲方的经营资质,在十五个 工作日完成审核,并进入小程序制作流程,若未能通过审核,则退还相应款项。 3、小程序开发服务费以本合同列明为准,甲方应于签订本合同当日一次性支付本合同项下全部服务费用,甲方未按上述约定支付的,乙方可拒绝提供本合同项下小程序开发服务。 三、甲方权利和义务 1、甲方有权享有本合同备注项目下的服务。 2、合同期满后甲方有权自主进行选择服务商,乙方应提供必要的协助。 3、甲方应该如实向乙方提供所需之相关信息(包括但不限于本合同填写之信息)凡因相关信息不真实,不准确等原因导致乙方无法或不能妥善履行本合同义务的,因此产生的一切后果由甲方负责。 4、甲方应当遵守相关法律及本合同项下服务内容相关的各项服务费用规定,甲方应保证本合同项下服务过程中甲方通过小程序发布传递信息的真实性、准确性、合法性和合理性;不能使用小程序开发服务从事任何违反法律及国家利益的事务;若乙方发现甲方有上述违约或违规行为,乙方有权选择立即暂停或终止行业门户网站服务,并有权不承担任何责任的单方解除本合同,甲方还应当给乙方适当的赔偿。 5、甲方应妥善保管小程序相关账号和密码,非因乙方原因造成甲方账号和密码泄露,被他人盗用等所产生的损失,乙方不承担任何责任。 四、乙方权利和义务 1、乙方为甲方提供小程序开发服务、技术支持及服务器。 2、未经甲方书面同意,乙方不得随意更改甲方提供的资料,乙方应对甲方的相关信息保密(司法机关或行政机关根据其权限调查除外)。 3、乙方负责在产品设计功能范围内解决甲方在小程序内容制作过程中遇到的技术问题。 4、乙方在维护管理服务器时,或由于乙方网站平台改版、升级、更新等,必要时可短时间中断服务。 五、责任 1、因甲方违反本合同的约定造成乙方收到相关部门处罚或者对任何第三方产生不良后果的,甲方应当赔偿因此给乙方造成的损失,并追究甲方其他的法律责任。 2、若乙方违反合同约定,甲方有权单方面终止合同,并要求乙方退回未履约的相应费用,并追究乙方的其他法律责任。 3、任何一方因不可抗力,致使对方受到重要经济损失,或导致本合同不能履行或不能完全履行时,受不可抗力影响的一方对另一方的损失不承担违约责任,本合同所指不可抗力,是指不能避免,不能实现的客观要求,包括但不仅限于地震、洪水等自然灾害、战争及政府行为、突发性公共事实等。 4、任何一方违反本合同约定的,应赔偿守约方因对方违约造成的全部损失,守约方有权解除本合同。 5、本合同履行过程中若发生争议,双方应友好协商解决,协商不成的,经双方同意后可将争议提交到仲裁委员会。本合同文本一式三份,具有同等法律效力 六、甲方须在合同签订之后预付百分之五十定金,项目开发周期内验收项目付全款之后确认上线。 七、本合同支付方式:口现金( 限10O元以下) 口支票(拍头必须填写下述收款单位) 口汇款口其它 收款单位:开户银行: 账号: 甲方(盖章):乙方(盖章): 授权代表签字:授权代表签字:

UI设计工作流程

UI设计工作流程 很多没有在正规的大公司工作过的设计师同学问过我面试时如果面试官问项目开发的工作流程是什么?其实,我觉得每个公司可能有自己的工作流程,有些些公司可能需要设计师从前期立项到中间开发到后期产品测试和项目上线的跟进要全程参与而有些公司可能只需要设计师在产品研发阶段进行参与,但不管那种方式,我觉得设计师有必要知道一个产品从立项到完成的所有步骤。现在我大概介绍一种工作流程给大家。 一、产品设计阶段 首先在一个项目开始之前会是立项,领导或者相关部门提出想法给产品经理,产品经理拿到项目之后,会对整个项目进行分析,这中间产品经理需要做很多工作。 1、首先产品经理配合市场部门进行市场分析,来搞清楚目标市场和产品定位,如果时 间充足的话,尽可能的也要做用户调研来确定产品的用户需求的挖掘和分析。 2、竞品分析也是产品经理和设计师都要做的功课。 3、这些前期工作完成之后,剩下的要做原型设计,预算产品周期,疏通整个产品流程,出原型图交给交互设计师 当然产品经理在做这些工作时是要保持时刻跟其他部门的同事密切共同的,例如产品的市场定位需要找市场部门的同事进行沟通,产品设计规范,界面布局等需要找UI设计师来沟通。而开发环境和项目周期可能要找到技术开发的同事来进行协调。有些公司还有专门的交互设计师,需要产品经理在前期制作原型图和交互设计师充分配合完成交互说明,以方便

后期的视觉设计和技术开发。 二、UI视觉设计 产品原型(包括前期交互稿)完成之后需要交付给UI设计师进行视觉设计,这里指的UI设计其实严格来说是属于GUI,因为UI的本意为user interface(用户界面)涵盖了交互设计,用户体验设计和视觉设计。而交互设计和用户体验是在产品开始之时就已经同时展开的,所以这里说的设计通常指的GUI界面视觉设计。 1、在UI设计师开始之前,要充分了解产品定位,通过目标用户的喜好风格分析开确定视觉设计的大概调性。 2、进行竞品分析,找出竞品优劣, 3、搜索素材灵感,多找优秀设计作为自己设计灵感的来源是一个非常有效的方法(参考学习而不是让你去抄袭)。 1)确定配色,布局和设计风格。 2)进行界面设计。 3)完稿后进行可用性测试,修改修改修改直至最重定稿。 在整个视觉设计中,设计师除了把控好整体的视觉设计风格,更要有耐心设计好各个细节,例如icon,字体,元素之间的间距等这些不起眼的地方往往代表了整个app的质量,细节之处做好,会给用户在视觉上带来一种安全可靠的感觉,所以细节非常重要。 这里有必要说一下视觉设计规范。有些公司的视觉规范是在视觉设计开始之前就要订下来的,而有些公司是整个视觉设计完成之后再来制定视觉规范。为什么可以这样呢,视觉规范是为了方便整个设计团队在设计时更容易进行沟通来进行的,而设计工作在进行中可能会随时进行变更视觉风格,所以设计前期来确定设计规范的话,可能会对后期的设计带来一定的限制,所以设计师内部可能会有一个简单的设计文档来进行交流。等设计稿定下来之后,再来制作标准的设计视觉规范,方便后期开发和之后设计工作继续跟进。 整个设计稿确定之后,设计师要出高保真视觉稿,交给技术来进行沟通,同时还需要对

人机界面设计原则 “以人为本” 1 以用户为中心的基本设计原则 在系统

人机界面设计原则 “以人为本” 1. 以用户为中心的基本设计原则 在系统的设计过程中,设计人员要抓住用户的特征,发现用户的需求。在系统整个开发过程中要不断征求用户的意见,向用户咨询。系统的设计决策要结合用户的工作和应用环境,必须理解用户对系统的要求。最好的方法就是让真实的用户参与开发,这样开发人员就能正确地了解用户的需求和目标,系统就会更加成功。 2. 顺序原则 即按照处理事件顺序、访问查看顺序(如由整体到单项,由大到小,由上层到下层等与控制工艺流程等设计监控管理和人机对话主界面及其二级界面。 3. 功能原则 即按照对象应用环境及场合具体使用功能要求,各种子系统控制类型、不同管理对象的同一界面并行处理要求和多项对话交互的同时性要求等,设计分功能区分多级菜单、分层提示信息和多项对话栏并举的窗口等的人机交互界面,从而使用户易于分辨和掌握交互界面的使用规律和特点,提高其友好性和易操作性。 4. 一致性原则 包括色彩的一致,操作区域一致,文字的一致。即一方面界面颜色、形状、字体与国家、国际或行业通用标准相一致。另一方面界面颜色、形状、字体自成一体,不同设备及其相同设计状态的颜色应保持一致。界面细节美工设计的一致性使运行人员看界面时感到舒适,从而不分散他的注意力。对于新运行人员,或紧急情况下处理问题的运行人员来说,一致性还能减少他们的操作失误。 5. 频率原则

即按照管理对象的对话交互频率高低设计人机界面的层次顺序和对话窗口莱单的显示位置等,提高监控和访问对话频率。 6. 重要性原则 即按照管理对象在控制系统中的重要性和全局性水平,设计人机界面的主次菜单和对话窗口的位置和突显性,从而有助于管理人员把握好控制系统的主次,实施好控制决策的顺序,实现最优调度和管理。 7. 面向对象原则 即按照操作人员的身份特征和工作性质,设计与之相适应和友好的人机界面。根据其工作需要,宜以弹出式窗口显示提示、引导和帮助信息,从而提高用户的交互水平和效率。 Apple Human Interface Guide——人机交互界面设计原则 人机交互原idliulei 则之1——隐喻 通过隐喻把人们对世界的理解转化为软件中的概念和特性是很有优势的。隐喻帮助用户建立任务的心智模型。使用通俗易懂的隐喻来表述具象或相似的概念,可以让用户对计算机环境有所掌握。比如说,Mac OSX 使用文件夹的隐喻表示储存文档的概念;用户可以整理他的硬盘,就和整理自己的档案柜一样。另一个例子是iTunes 的播放列表和iPhoto 的相册,它们就像现实世界里的音乐播放列表和相册一样。Dashboard 里的widget 也是一种隐喻,因为它需要完成的任务目的能够直接传达给用户。(可以参见Dashboard widget的设计指引。) 对于某个元素,隐喻可以建议它的使用方式,但是使用方式不应该被隐喻的实现所限制。在隐喻所建议使用方式与电脑能实现、扩展隐喻的能力之间要保持好平衡。举例来说,用户放到回收站的东西数量不应该被真正垃圾桶能容纳的东西数量所限制。 人机交互原则之2——反映用户的心智模型

小程序服务类目

小程序服务类目选择 一、快递业与邮政 1、快递、物流 2、仓储 3、邮政 4、装卸搬运 二、教育 1、学历教育 2、出国留学 3、教育装备 4、婴幼儿教育 5、在线教育 三、医疗 1、就业服务 所需材料:

签订协议的医院列表及其中的一份协议及其中的一份承诺书及协议医院的《医疗机构执业许可证》或者卫生和计划生育委员会/医管局批文【签订协议的医院列表上传原件或复印件,复印件务必加盖公司公章】 2、私立医疗机构 所需材料: ①《增值电信业务经营许可备案》上传原件或复印件,复印件务必加盖公司公章 ②《医疗机构执业许可证》上传原件或复印件,复印件务必加盖公司公章 3、药品信息展示 所需材料: 《互联网药品信息服务资格证》上传原件或复印件,复印件务必加盖公司公章 4、医疗保健信息服务 所需材料: 增值电信业务经营许可备案》上传原件或复印件,复印件务必加盖公司公章

5、公立医疗机构 所需材料 ①《医疗机构执业许可证》上传原件或复印件,复印件务必加盖公司公章 ②《组织机构代码证》上传原件或复印件,复印件务必加盖公司公章 6、医疗器械信息展示 所需材料: 《互联网药品信息服务资格证》上传原件或复印件,复印件务必加盖公司公章 7、医疗器械生产企业 所需材料: 《医疗器械生产许可证》上传原件或复印件,复印件务必加盖公司公章 8、医疗器械经营、销售 所需材料:《医疗器械经营许可证》上传原件或复印件,复印件务必加盖公司公章。 9、互联网医院

所需材料: ①《卫计委批文》上传原件或复印件,复印件务必加盖公司公章 ②《ICP备案》上传原件或复印件,复印件务必加盖公司公章 ③《合作医院的医疗机构执业许可证》上传原件或复印件,复印件务必加盖公司公章 10、药品(非处方药)销售 所需材料: 《互联网药品信息服务资格证》及《药品生产许可证》或者《互联网药品信息服务资格证》及《药品经营许可证》 11、血液中心、血库及干细胞库 所需材料: 《血站执业许可证》或者政府有关部门批文 12、健康咨询/问诊 ①《增值电信业务经营许可备案》上传原件或复印件,复印件务必加盖公司公章 ②《医疗机构执业许可》上传原件或复印件,复印件务必加盖公司公章

实验8_图形界面程序设计

山西大学计算机与信息技术学院 实验报告 姓名学号专业班级计算机科学与技术 课程名称 Java实验实验日期2014/5/29 成绩指导教师陈千批改日期 实验名称实验8 图形界面程序设计 一、实验目的 掌握常用GUI控制组件及其事件处理。 二、实验内容 1.编程包含一个标签和一个按钮,单击按钮时,标签的内容在“你好”和“再见”之间切换。 程序代码: import java.awt.Color; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class ChangeGUI extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JButton button; private JLabel label; public ChangeGUI() { super("Say Hello"); JPanel panel = new JPanel(); JPanel panel2 = new JPanel(); setLayout(new GridLayout(2, 1, 0, 5)); button = new JButton("OK"); button.setBackground(Color.ORANGE); button.setForeground(Color.RED); panel.add(button); button.addActionListener(new OKActionListener()); label = new JLabel("你好");

售后服务程序及流程

售后服务程序及流程 一对于不合格产品的处理 (1)客户在使用中由于自身原因造成产品或配件损坏,由客户承担费用(按最近市场价收费),有维修工人负责安装、维修,并在客户同意的情况下处理已经损 坏的产品; (2)客户在使用中发现产品出现问题,经工作技术人员鉴定后,确定不是客户原因导致产品损坏,拍照后报予集团解决. a对于更换或赔偿数额较小者,由本部门直接处理,更换或赔偿后,及时上报财务及主管经理; b对于更换或赔偿数额较大者,由主管与技术人员前往客户家中,经鉴定后, 与客户双方达成协议,总经理审核后,对客户予以赔偿;对客户使用产品在 双方协调下处理后,搜集客户相关资料,填写《产品质量处理核销申报表》。二跟踪 客户使用中出现任何问题,都应及时安排好维修人员为客户解决问题。 1售后服务宗旨 客户第一——“完全满意的客户服务” 2售后工作职能 (1)负责所在区域的日常售后服务工作,认真接听服务热线,回答客户疑难问题; (2)在接待客户来电时,应用礼貌用语,对待客户投诉时,认真听取客户意见,不能与客户在电话内吵架,对客户投诉案例进行分析,并在72小时内提出处理 方案,在《维修受理表》上建立客户售后服务档案;将处理方案通知客户,并 根据客户要求合理安排时间维修; ↓ 是↓↓否 ↓ ↓↓↓↓ ↓ 三回访 1 将安装好的客户售后服务卡进行登记汇总; 2 按周、一个月、三个月、半年和一年及时进行回访; 3电话访问要热情、真切,如果客户有相关产品问题,要及时回答并予以解决。 4流程 ↓↓

↓↓ ↓ 5程序细则 (1)“你好,我是梦天集团黄石公司的售后服务,现在您是否方便,我可以打扰您一下吗?”,如果对方不方便,“很抱歉占用您宝贵的时间,有机会我们会再打 给您的。”如果对方有时间,接着说 (2)“非常感谢您对我们产品的信任,X月X日我们为您安装的木门满意吗?对我们的销售、施工、产品等有什么意见和要求,欢迎您为我提出来,看看我们能 为您 做点什么”。一般会有以下情况; a客户对我们的产品和我们的工作表示满意,并且没有其他要求时,我们接受 得到的赞扬,并说:“谢谢,这是我们应该做的,我们会努力做得更好,如 果您需要我们帮助时,请拨打我们的服务热线,我们会按照您的要求竭诚为 您服务。”最后道别,并表示:“打扰您了。” b我们的工人如果真的做的非常出色,感动了客户,客户会借此机会表示他的 谢意,这时,我们更应该谦虚地说:“这是我们应该做的,我们会努力做到 更优秀。”之后,应该将客户提供的好人好事向公司领导汇报。 c客户会将他的不满说出来,我们耐心听完后,帮他分析原因,将他的疑虑消除, 需要我们进一步完善的工作,要告诉对方:“很抱歉给您带来了不必要的麻烦, 我们将会对您的问题马上备案,等您方便时我们会派专门的技术人员为您解 决问题,好吗?”然后要将客户的情况及时反映给相关部门,并根据情况赠 送公司的小礼品给他,以表诚意。同样,对待恶劣的事件也要向总经理汇报, 达到提高员工素质的目的。 (3)如果客户说现在不方便谈,我们一定要快速表示歉意,并简洁地问明什么时候方便打电话,千万不要浪费对方的时间。 (4)如果我们打通的是客户的手机电话,我们一定要说:“打扰您了,我是梦天集团黄石公司售后服务,打您手机方便吗?如果您愿意,请告诉我有线电话,我 马上重新打给您。”让对方选择通话方式,再接着下面的交谈。 6回访结束后,要认真作好记录,对需要进一步做的工作,按客户投诉处理流程进行。 7对所有回访资料要输入电脑保存,便于查找。每月将回访中得到的信息归类总结,使长处继续发扬光大,不足之处加以弥补,使我们的产品质量和服务质量不断提高。

实验三图形用户界面设计(汽院含答案)

实验三图形用户界面设计 实验目的 1.掌握Java语言中GUI编程的基本方法 2.掌握Java语言中AWT组件的基本用法 3.掌握Java语言中Swing组件的基本用法 实验导读 1.通过图形用户界面(GUI:Graphics User Interface),用户和程序之间可以方便地进 行交互。 AWT(Abstract Windowing Toolkit),中文译为抽象窗口工具包,是Java提供的用来建立和设置Java的图形用户界面的基本工具。AWT由Java中的java.awt包提供,里面包含了许多可用来建立与平台无关的图形用户界面(GUI)的类,这些类又被称为组件(components)。 Swing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。 JDK写程序所有功能都是靠虚拟机去操作本地操作系统。比如window下,就是JDK 用windows API实现功能。而awt包中很多组件是组件自身去调用本地操作系统代码swing包中的组件采用的是调用本地虚拟机方法,由虚拟机再调用本地操作系统代码。意思就是中间多了一层,这样就加强了swing包的移植性,与本地关系不那强了。 图3.1 AWT常用组件继承关系图 Container为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。 2.布局,容器中的组件的排放方式。常见的布局管理器: FlowLayout(流式布局管理器):从左到右的顺序排列。Panel默认的布局管理器。 BorderLayout(边界布局管理器):东,南,西,北,中。Frame默认的布局管理器。 GridLayout(网格布局管理器):规则的矩阵

客户服务标准流程

客户服务管理流程 A.接待: 1.顾客进店后,接待生或顾问应热情主动上前问候,保持热情的姿态,以专业的礼仪和专业术语,面含微 笑,迎客入内,让顾客觉得院内人员有修养、有气质、有专业水平; 2.客人进店后,应安排客人就座,倒好茶水,按公司规定交由相关顾问予以咨询。 B、咨询: 1.顾问接到客人后,如果是新客,应主动咨询客人有什么需求,并询问客人以前是否曾到本院或询问客人 是如何得知本院的,对客人的到来表示谢意; 2.针对客人的需求,顾问应详细地介绍本院的服务项目、服务品质,根据顾客本身需求之特点向顾客推荐 最好的服务内容给顾客选择; 3.如果是本院的老客人,应先询问客人有否存卡,把客人的档案找出; 4.无论是新客人或旧客人,在询问的过程中,应做好相关美容参数的检测工作,并记录在档案内,根据客 人的皮肤、身体状况,帮客人设计疗程; 5.向客人介绍你给她建议的产品及护理方法,并说明能达到之效果,征得客人的意见,满足客人之需求; 6.当询问完毕客人愿意接受我们之服务时,应马上通知相关美容师做好准备,并亲自带客人放臵好随身物 品,交给美容师予以服务,并告知美容师应特别注意之事项。 C、服务: 1.美容师接到顾问交给的客人后,应热情接待,请顾客躺在美容床上,包好头,盖好被子,并询问姿势是 否舒服; 2.在顾客面前美容师应做好清洁消毒工作,严格贯彻从一盆清水做起的原则,向客人解说每道程序的作用; 3.在服务过程中,根据顾客的心情或当天的身体状况与客人聊天,如果是新客尽量不要推销产品,如果是 旧客人,聊天过程中既可推销产品或其他疗程; 4.当顾客非常疲惫时,美容师可以说“今天好好休息吧”之类的话,不许东拉西扯; 5.当顾客显得不耐烦或赶时间,美容师应尽量手脚利落地处理或加快疗程,在轻松、舒适的环境和心情下 聊天,可以进一步深化彼此的了解、融洽关系、在操作中应随时细心地留意顾客的反应,适时调整话题,达到进一步介绍项目和产品之目的; 6.护理结束后,用镜子向顾客显示效果,征求顾客意见,帮助客人整理好容妆,一举一动都应体现你的细 致及专业水平,真诚赞美顾客,最后把客人交回顾问并做好相关移交工作,把服务过程中客人的一些需求告知顾问。 D、再咨询: 1.当顾问接到美容师服务结束之客人后,应真诚赞美客人“效果真不错”、“漂亮了很多”之类的话,然后 倒茶再咨询; 2.顾问安排好客人后,应再咨询客人对我们的服务的意见,及对美容师的感觉,是否服务周到,对客人的 意见应专心聆听,并做好记录,以便事后改善; 3.再给客人测试美容后之相关参数,与美容前比较用数据来显示效果,并记录在客人的档案内; 4.为了让客人更满意我们的服务,应建议客人事后在工作、生活中应注意什么事项及适当的家居护理,介 绍相关的产品,使效果更佳,让客人满意; 5.顾问在处理好上述事宜后,应同客人预约下一次服务时间。 E、送客: 1.再咨询客人后,应热情地带客人到前台结帐; 2.当客人离开时,提醒她是否带好了所有物品,送她到门口,希望她下次光临,态度诚恳,语言真挚,并 衷心地谢谢客人的光临; 3.客人送走后,顾问应认真地做好档案记录工作,几天后主动与顾客联系,了解她们护理后的情况,并进 行下次的预约工作,要用真诚来感动顾客,留住客人的心。 客户服务管理流程

系统界面设计规范标准

B/S 系统界面设计规 1.引言 界面美观、操作易用性、维护成本低是评价B/S系统的关键。本规参考了一些成熟产品科学的开发方法,将开发过程中的方式、规则等强行的约束。希望藉此来提高用户操作感受,提升B/S产品的质量。 1.1. 编写目的 广义的界面概念包含了除页面布局设计之外,交互性的设计,及人体工程学方面的研究。本规制订的依据从广义概念出发,总结以往项目的成败经验,目的是从整体上提升公司B/S 类产品的质量、开发效率。从以技术为中心发展为以客户为中心,将类似项目成功的经验继承和积累下来,将B/S系统与C/S系统开发过程上的区别降低到仅显示控制的极小的层面。新的开发方式强调分层,规出界面设计人员做什么,服务器编程人员做什么,这样就把页面和控制代码两个层面清晰的分开。 1.2. 背景 B/S模式系统以其易部署、易扩展、能够高度集成各种技术的特点,在公司产品线中占越来越大的比重,.Net、J2ee等技术的发展更是将B/S系统的开发和桌面应用程序开发的工程方法统一起来,突出服务器端技术,这些变革要求界面设计人员和服务器端编程人员可以应用更加科学的方法合作,团队的合作方式甚至决定了一个系统开发的成败。目前公司较多的服务器端编程人员仍然处于“后ASP 时代”的开发方式,表现为前台页面仍然与服务器代码高度的关联,带来的后果是重复建设、高昂的维护成本或失去控制的项目,没有充分的发挥出集成开发工具的优势。在以往的开发方式下界面设计侧重在静态页面的建设上,每个页面作为一个独立的模块来处理,在页面交互中则是程序员根据自己的习惯来控制,程序对个人的编程风格的依赖很强,这些在以往开发WEB站点的方式扩展到B/S系统有时是不正确的,甚至是背道而弛的,当然也不利于规模化的团队合作。 1.3. 定义 术语定义: 效果图:由界面设计人员设计的页面效果图,综合了概要设计的业务需要和整个站点的风格,它规定了页面布局上的每个细节。 容器:即HTML 标记的嵌套结构,如在表格->行->单元格放置图片,那么可以认为单元格是放置图片的容器。 样式表:即级联式样式表CSS,它是W3C机构在HTML标记语言上扩展的格式语言。 非标准交互控件:是通过标准控件组合、扩展等方法以提高特定业务执行效率而进行封装的控件,或概括为用户根据以往的操作经验不能够直接领会出操作方式的交互控件。 2. 界面设计规细则 总体目标 以规作为基本原则,在此框架进行合理的扩展和变化,将站点的每个模块服从于整个站点,模块页面与“高聚”的控制代码紧密的结合在一起,同时对应于应用程序基于系统的架构分析。 2.1. 通用原则 1 界面色彩要求:计算机屏幕的发光成像和普通视觉成像有很大的不同,应该注意这种

小程序开发客户服务流程

小程序开发客户服务流 程 公司内部编号:(GOOD-TMMT-MMUT-UUPTY-UUYY-DTTI-

微信小程序开发客户服务流程 一、售前 二、1、客户需求确认,签订合同 商务人员签订合同前,务必明确客户需求,形成明确的书面需求文档,作为合同的附件和具体开发的交付依据。 书面需求文档当明确如下要点: 软件开发具体功能如下,举例:商城在线交易、订单处理、营销活动、分销功能、团队分红、多商户等。 开发搭建交付要求,举例:店铺主页搭建、商品上传**款、营销活动配置、分销功能完善、海报设计等。 售后培训说明:线上培训、线下集中培训或者上门培训(500元/次/半天)。 2、设计风格案例参考 商务人员在签订合同后,需依据客户的行业类别及产品风格,推荐风格相近的案例,供客户参考,初步确定整体设计风格及要求。 3、菜单内容规划沟通 依据客户的具体需求,做好公众号、小程序菜单/导航具体的内容规划和对应的资料素材收集要求。参考如下:

三、开发制作 1、指定对接人:甲方需指定具体事项唯一对接人,我方以收到对接人提供的资料、素材之日起,正式计算开发日期。 2、账号注册认证:甲方需提交注册认证的基本资料,包括邮箱、电话、运营人员身份证照片及微信验证、对公账户资料、特殊行业特定资质等;并且,甲方人员应当予以配合。一般3-7个工作日完成微信认证。 3、微信支付申请:甲方需提供申请微信支付的基本资料:商户联系人姓名、联系电话、联系邮箱;商品简介、商户简称、售卖商品类目、售卖资质证件;结算银行信息、结算银行卡号等。一般3-7个工作日完成支付申请。 4、搭建开发资料对接:甲方需按我司提交的公众号菜单规划表格所列资料素材需求,提交到我司指定对接人员的邮箱。 5、上线测试,提交审核:我司完成基础开发搭建后,运营部门、商务部门人员先完成功能测试,再提交甲方初审。

程序界面设计

设计“好看”的用户界面(王咏刚 2003年10月) 1 问题引入 两周前,我的一个朋友小W找我聊天,跟我说了件烦心事儿:他们公司开发的一套行业软件在竞标时败给了竞争对手;当时,用户给出的理由是,小W他们的软件界面粗糙、简陋,看上去远不如竞争对手的界面那么专业。当然,小W和我都明白,对于竞标失败而言,这个理由并不充分——在行业软件市场上,大多数竞标失败都有着更深的背景原因,比如客户关系的好坏;但在公开场合里,软件性能、售后服务、用户界面等更为冠冕堂皇的理由却总能成为客户拒绝你的最好托词。为了不在今后的竞标中被客户和竞争对手轻易抓住把柄,小W下决心改进他们的软件界面。 经过研究,小W和同事们发现,他们公司开发的所有软件几乎都存在用户界面粗制滥造的通病。程序员们经常随心所欲地设计窗口、摆放控件,图标、字体和颜色的使用也没有统一的标准,由此开发出来的软件尽管在功能和性能上都表现得非常出色,但界面大多简陋不堪,一眼看上去就像是土法烧制的陶盆儿陶罐儿——单独摆在桌上还不觉得怎样,一旦和官窑里烧出的上等瓷器摆在一起,立马就会相形见绌,惨不忍睹。 为了改变现状,小W他们的第一反应是请专业的美工来主持界面设计工作。小W说:“好看不好看的问题当然属于艺术范畴。程序员们都是工程师,没有半点儿艺术头脑,再怎么折腾也是白搭。所以,我们一定要请专职的平面设计师来设计界面,程序员只要按照设计师的思路编程实现就行了。” 这个主意听上去不错,小W也的确从广告公司请来了一位平面设计师。 “当然,像麦肯、奥美那样的大广告公司我们也请不起。我们请的那人是专做平面设计的,身价不高,在行里却也小有名气——当然,比我们这些外行强多了。” “那么后来呢?”我喝着咖啡不怀好意地问,那情形就像是电影《绿茶》里姜文在向赵薇刨根问底。 “后来?要是后来一切都OK了,我还找你干什么?”小W把一肚子苦水倒在我面前。原来,平面设计师来到小W的公司以后,工作还算努力,也画出了许多漂亮的界面设计稿,但程序员们就是没法把这些设计变成现实:要么是设计出的界面像游戏软件的界面一样动感十足,让人难以接受(用户方的领导绝不会容忍下属们对着游戏画面优哉游哉地完成日常工作);要么是设计出的界面与软件的功能自相矛盾,必备的功能没法融入到界面之中(比如,为了保证美观,设计师限制了子窗口的大小,结果好几个控件就找不到立锥之地了);要么是界面设计得过于前卫,根本就无法用现有的窗体或控件技术实现……光是这些技术问题还不算什么,最要命的是,设计师经常对程序员们指手划脚,总是说“你们不懂,这是艺术规律”。结果,艺术规律败给了严酷的现实:当平面设计师给出的方案一次又一次被程序员们否决,大多数程序员开始消极怠工了,几乎所有人都放下了手头的工作,一边摇头一边嘟哝:“界面都定不下来,还编什么程序?”。 “你说,我该怎么办呢?”小W痛苦地问。 “你说呢?”我幸灾乐祸,一脸坏笑。 2 一些题外话 像其他软件开发环节一样,用户界面设计也可以借助一些现成的工具。 有一次,我们要为客户准备一个产品方案。方案里的好几个软件模块我们从来就没有真正实现过(这种“空手套白狼”的做法在行业软件市场里相当普遍)。为了让我们的方案更有说服力,售前工程师们干脆用制图软件Visio 里的用户界面绘制功能,把尚未问世的软件模块画得有模有样,窗体、菜单、按钮、工具栏、对话框等界面元素也都一应俱全。在方案里集成了这些界面图片以后,半数以上的用户就不会怀疑这套系统的真实性了——毫无疑问,这也是一种界面设计工作,尽管其中有些招摇撞骗的味道。 应当说,要描述和展现用户界面设计方案,最直观的方法就是把界面的样子画出来。在程序员看来,白板或稿纸上的一张界面示意图往往就能说明所有问题。不过,当我们需要在不同的开发环境中交换设计方案,或是要管理和检索界面设计文档的时候,图片信息就不如格式化的文本信息那样方便了。为此,人们陆续设计出了许多“用户界面描述语言”。利用这些语言,我们可以像编写程序那样“编写”用户界面。比如说,Delphi中用来描述窗体特性的*.dfm文件,其中的文本内容就是一种相当不错的用户界面描述语言。 与其他描述性语言类似的是,用户界面描述语言也有标准化和XML化的倾向。迄今为止,人们已经提出了AAIML、AUIML、XIML、XUL、UIML等一系列基于XML 标准的用户界面描述语言①。W3C正在制订的XForms标准②也是XML家族的一员,它很可能成为未来设计和开发Web用户界面的核心技术之一。 有关用户界面描述语言的研究和探索工作的确有助于

《面向对象程序设计》课程界面设计练习题目

《面向对象程序设计》课程界面设计练习题目 Windows NT系统内建了若干个的常用控件,极大地方便了Windows下可视化程序的开发。对于初学者来说,能够熟练地使用这些控件,是学好C++面向对象编程的关键步骤。 为了指引初学者或者检验学习效果,下面设计了五个练习题目,囊括了大部分的常用控件,以及程序界面开发中常常使用的技术。练习题目如下: 一、播放器配置程序 二、消息提示器 三、流媒体管理器 四、可定制背景的视图 五、通讯簿

一、播放器配置程序 内容: 制作一个基于对话框的播放器配置程序,能够从配置文件(*.ini )中读取设置信息;能够将修改后的设置信息保存在配置文件中。界面如图1所示: 图1 播放器设置界面 目的: 掌握使用VS 建立基于对话框的应用程序;熟悉标签(Static Text )、分组(Group Box )、按钮(Button )、编辑框(Edit Control )、组合框(Combo Box )、单选按钮(Radio Button )、复选框(Check Box )、热键设置控件(Hot Key )等常用控件的属性、事件;掌握配置文件(*.ini )的读写;学习MSDN 文档的查阅等。 要求: 1、 控件1(组合框):不可输入文字,只能从下拉列表中选取一项,列表中的 内容为:简体中文、繁軆中文、English ; 2、 控件2(复选框):默认勾选。 3、 控件3(热键设置控件):当控件2勾选时,控件才3可编辑;当控件2未1 2 3 4 5 6 7 8 9 12 13 14 15 16 10 11

勾选时,控件3灰掉(不可编辑); 4、控件4~7(复选框):默认勾选控件4和控件5; 5、控件8(编辑框):只能输入数字,范围1~60; 6、控件9~11(一组单选按钮):默认选中控件9; 7、控件12(按钮):当点击按钮时,在13中输出如图1所示的文字; 8、控件13(编辑框):能够输入换行符,具有垂直滚动条,当文本框内容不能 全部显示时,滚动条自动有效; 9、控件14~16(按钮):按钮15初始不可用,当更改设置信息后才激活;接收 回车提交命令;点击该按钮,将新的设置信息(控件12和13不触发配置信息改变)写回与程序同目录下,名称为config.ini配置文件中; 点击按钮14时,如果设置信息有更改,将设置信息写入配置文件,并关闭对话框;若设置信息未发生改变,直接关闭对话框; 点击16直接关闭对话框; 10、配置文件读写要求:程序启动时若没有找到配置文件,能够按照默认设置 初始化界面(按钮15激活),点击按钮14和15生成配置文件并写入设置信息,点击16则不生成配置文件;若找到配置文件,从文件中加载配置信息并初始化程序界面; 11、对话框样式:对话框可以最小化,不能最大化,不可以改变大小;界面布 局要工整;对话框初始时控件1取得焦点,按tab键焦点将按图中标注的序号逐一移动到下个控件上。 提示: 1、复选框勾选状态的获取:可以将复选框与一个BOOL变量关联,通过BOOL 变量得知其勾选与否;也可以获取其控件状态(state)来得到是否被勾选; 可以响应复选框的单击事件来处理复选框状态改变时的任务; 2、单选按钮组的概念:点选按钮有组的概念,同一组内的单选按钮相互排斥, 只能有一个被点选;一个单选按钮A若具有GROUP=true属性,则紧跟其后的GROUP=false属性的单选按钮同A为一组,可以为A关联一个int型变量,改变量反应了该组内那个按钮被点选; 3、配置文件的读写:配置文件(*.ini)为文本文件,常用于保存配置信息;系统具 有GetPrivateProfileString、WritePrivateProfileString等函数用于操作配置文件,具体可参见MSDN中相关介绍; 4、使用Tab键移动焦点:需要控件具有Tabstop属性;焦点移动的顺序与界面 控件的排放顺序有关,可以在界面编辑界面按Ctrl+D显示控件的序号,在序号上点击可以修改控件的顺序。

相关文档
最新文档