指导培养青年教师证明你我可以用模拟盘带你,证明下技术

问题补充&&
本页链接:
猜你感兴趣
服务声明: 信息来源于互联网,不保证内容的可靠性、真实性及准确性,仅供参考,版权归原作者所有!Copyright &
Powered by当前位置:
MS Active Accessibility 接口技术编程尝试
MS Active Accessibility 接口技术编程尝试
发布日期: 10:11
浏览次数:9982次
标  签:windows
文章评分:5.0
操  作:
称号:未设置简介:...
文章概要:
Microsoft(C) Active Accessibility 是一种相对较新的技术(1.0版在1997年5月份推出)。目的是方便身患残疾的人士使用电脑——可用于放大器、屏幕阅读器,以及触觉型鼠标。同样还可以用来开发驱动其它软件的应用程序,其模拟用户输入的能力尤其适合测试软件的开发。
Active Accessibility 的主要思想是提供一种以程序方式访问UI元素信息或操作这些UI元素的功能。支持这种功能的 UI(User Interface) 元素是可访问的。在大多数情况下,这意味着一个UI元素支持 IAccessible 接口。你也可以说在 Active Accessibility 的世界里,一个可访问的UI元素可表示为 IAccessible 接口。
每当你需要得到有关一个元素的信息,在其上执行一个动作,或者使用 Active Accessibility 做其它的什么,你通常需要通过使用代表这个元素的 IAccessible 接口的一种方法或者属性来引用这个元素......
Microsoft Active Accessibility 2.0 is a COM-based technology that improves the
way accessibility aids work with applications running on Microsoft Windows?. It
provides dynamic-link libraries that are incorporated into the operating system
as well as a COM interface and application programming elements that provide
reliable methods for exposing information about user interface elements.&&&&&
Microsoft Active Accessibility 是一种相对较新的技术(1.0版在1997年5月份推出)。目的是方便身患残疾的人士使用电脑――可用于放大器、屏幕阅读器,以及触觉型鼠标。同样还可以用来开发驱动其它软件的应用程序,其模拟用户输入的能力尤其适合测试软件的开发。
Active Accessibility 的主要思想是提供一种以程序方式访问UI元素信息或操作这些UI元素的功能。支持这种功能的 UI(User Interface) 元素是可访问的。在大多数情况下,这意味着一个UI元素支持 IAccessible 接口。你也可以说在 Active Accessibility 的世界里,一个可访问的UI元素可表示为 IAccessible 接口。
每当你需要得到有关一个元素的信息,在其上执行一个动作,或者使用 Active Accessibility 做其它的什么,你通常需要通过使用代表这个元素的 IAccessible 接口的一种方法或者属性来引用这个元素。
Active Accessibility 原理
Active Accessibility? 的核心功能由 OLEACC.DLL 提供的。每次当你调用一个函数来返回一个 IAccessible 接口指针,其与一个UI元素相对应,OLEACC.DLL就检查此元素是否内在支持 IAccessible。内在的支持意思是该元素的 IAccessible 是用程序实现的。
当一个UI元素不能内在的支持 IAccessible 时,OLEACC.DLL 检查该元素的Windows 类名。如果该类是一个 USER 或者 COMCTL32 支持的类,OLEACC.DLL 就创建一个代理为 UI 元素实现 IAccessible 接口。大多数--但不是全部--COMCTL32 控件都具有被 OLEACC.DLL 支持的 IAccessible 接口。
内在支持 IAccessible 的 UI 元素的例子是定制控件,owner-drawn 和无窗口的控件。因为开发者创建的程序包含这些UI元素,同样就实现了这些元素的接口,他们有责任为这些方法和属性提供正确的支持。
如果你用标准控件,这也意味着你不必重写你的应用,这些应用自动与Active Accessibility兼容。
Active Accessibility 名字是基于 Win32 控件的名字给出的,角色基于控件的功能定义。
如何得到 IAccessible 接口指针
每当你需要有关一个元素的信息,在其上执行一个动作,或者使用 Active Accessibility 做其它的什么,你只需要通过使用代表这个元素的 IAccessible 接口的一种方法或者属性来引用这个元素。
有几种方法取得代表一个可访问 UI 元素的 IAccessible 接口的指针。最普通的方法是使用 Active Accessibility 提供的一种函数,例如 AccessibleObjectFromPoint,AccessibleObjectFromWindow 等等,或者使用 IAccessible 支持的方法,例如 get_accChild,get_accParent。
IAccessible 接口支持允许你得到各 UI 元素信息的属性,而其中对于例子程序最重要的属性是名字、角色和状态。
Active Accessibility SDK提供了一些方便的工具,其中的 Object Inspector 能显示光标指向的UI元素的属性。Object Inspector 显示了Active Accessibility 的世界如何因为具有支持一个选定窗口内的 IAccessible 接口的控制而变得通用了。除了搜索有关元素的信息和通过 IAccessible 接口控制元素以外,Active Accessibility? 还有两种对于例子程序非常有用的特性:监视UI元素发生的事件和模拟键盘、鼠标输入。由可访问的元素激发的事件称为 WinEvents,当可访问的元素创建或者名字、状态、位置或者键盘焦点发生变化时,就激发这些事件(事件机制类似于标准的 Windows 的 hook 机制。监视事件我们将在后面介绍。)。这些事件的清单见文件 WINABLE.H。每个事件的名字以 EVENT_OBJECT 或 EVENT_SYSTEM 开始。
好,我们言归正传,来介绍如何得到 IAccessible 接口指针。前面已经提到过 AccessibleObjectFromWindow 这个 Active Accessibility 提供的函数,从字面上大家可以看出是通过窗口来得到对应的 IAccessible 接口指针。
因为 IAccessible 接口的数量比窗口要多(因为大多数--但不是全部--COMCTL32 控件都有被 OLEACC.DLL 支持的 IAccessible 接口。),使用 Win32 函数来搜索一个窗口将会比使用 Active Accessibility 树搜索与该窗口相应的 IAccessible 接口要占用少得多的时间。这就意味着为了提高性能,你应该使用 FindWindow 和 EnumWindows 这样的 Win32 函数来找到与希望的UI元素最接近的窗口。当然,在权衡 Win32 函数和 Active Accessibility 函数时,上面的规则只是使用它们的一般标准而不能盲目的遵照执行,重要的是理解它们的本来意义。
下面结合代码介绍一下它的用法。
我们来得到下面运行窗口的 IAccessible 接口指针。
HWND hWndMainW
IAccessible *paccMainWindow = NULL;
//得到标题为"运行"的窗口的句柄
if(NULL == (hWndMainWindow = FindWindow(NULL, "运行")))
MessageBox(NULL, "没有发现窗口!", "错误", MB_OK);
//通过窗口句柄得到窗口的 IAccessible 接口指针。
if(S_OK == (hr = AccessibleObjectFromWindow(
hWndMainWindow,
OBJID_WINDOW,
IID_IAccessible,
paccMainWindow)))
//……我们可以通过这个指针paccMainWindow进行操作。
paccMainWindow-&Release();
现在我们已经得到窗口的 IAccessible 接口指针了(paccMainWindow),那么,我们可以干什么呢?我们怎么得到窗口中某个控件的 IAccessible 接口指针呢?我们就以上面的运行窗口为例。看看如何得到文本框的 IAccessible 接口指针!!
首先我们启动 inspect32.exe,什么?你不知道这是什么东西?赶紧先下载个Active Accessibility SDK看看吧……
然后,把鼠标放到所关注的控件上(即上图中的文本输入框),你会得到如下信息:
我们现在主要关注的信息是:Name、Role、Window className。
Name = "打开(O):"
Role = "可编辑文字"
Window className = "Edit"
当开发自定义、owner drawn 或者无窗口的控件时,为同一窗口的每个"角色-名字"指定独一无二的表示是一个非常好的编程习惯。然而,如果由于某种原因,同一窗口中的2个 UI 元素具有同样的"角色-名字"对,那么就需要增加一个参数--windows 类--以唯一的来表示这个元素。
FindChild 函数显示了一个基于 Active Accessibility 父/子(你可以理解成父窗口/子窗口的关系,只是为了便于理解:-P)导航的搜索例程的实现。这个函数有6个参数。前4个包含传递给函数的信息,后2个包含了 IAccessible 接口/子ID对(见附录)。
下面我们开始取文本输入框的 IAccessible 接口指针。
IAccessible* paccControl = NULL;//输入框的 IAccessible 接口
FindChild( paccMainWindow,
"打开(O):",
"可编辑文字",
&paccControl,
&varControl )
第一个参数是先前得到的窗口 IAccessible 接口指针。
第二、三、四个参数分别是名字、角色、类。
后2个为返回参数包含了 IAccessible 接口/子ID对。下面是FindChild的实现。
BOOL FindChild (IAccessible* paccParent,
LPSTR szName, LPSTR szRole,
LPSTR szClass,
IAccessible** paccChild,
VARIANT* pvarChild)
unsigned long numF
VARIANT varC
IAccessible* pCAcc = NULL;
IEnumVARIANT* pEnum = NULL;
IDispatch* pDisp = NULL;
BOOL found =
char szObjName[256], szObjRole[256], szObjClass[256], szObjState[256];
//得到父亲支持的IEnumVARIANT接口
hr = paccParent -& QueryInterface(IID_IEnumVARIANT, (PVOID*) & pEnum);
pEnum -& Reset();
//取得父亲拥有的可访问的子的数目
paccParent -& get_accChildCount(&numChildren);
//搜索并比较每一个子ID,找到名字、角色、类与输入相一致的。
for(index = 1; index &= numChildren && ! index++)
pCAcc = NULL;
// 如果支持IEnumVARIANT接口,得到下一个子ID
//以及其对应的 IDispatch 接口
if (pEnum)
hr = pEnum -& Next(1, &varChild, &numFetched);
//如果一个父亲不支持IEnumVARIANT接口,子ID就是它的序号
varChild.vt = VT_I4;
varChild.lVal =
// 找到此子ID对应的 IDispatch 接口
if (varChild.vt == VT_I4)
//通过子ID序号得到对应的 IDispatch 接口
pDisp = NULL;
hr = paccParent -& get_accChild(varChild, &pDisp);
//如果父支持IEnumVARIANT接口可以直接得到子IDispatch 接口
pDisp = varChild.pdispV
// 通过 IDispatch 接口得到子的 IAccessible 接口 pCAcc
if (pDisp)
hr = pDisp-&QueryInterface(IID_IAccessible, (void**)&pCAcc);
hr = pDisp-&Release();
// Get information about the child
//如果子支持IAccessible 接口,那么子ID就是CHILDID_SELF
VariantInit(&varChild);
varChild.vt = VT_I4;
varChild.lVal = CHILDID_SELF;
*paccChild = pCA
//如果子不支持IAccessible 接口
*paccChild = paccP
//跳过了有不可访问状态的元素
GetObjectState(*paccChild,
&varChild,
szObjState,
sizeof(szObjState));
if(NULL != strstr(szObjState, "unavailable"))
pCAcc-&Release();
//通过get_accName得到Name
GetObjectName(*paccChild, &varChild, szObjName, sizeof(szObjName));
//通过get_accRole得到Role
GetObjectRole(*paccChild, &varChild, szObjRole, sizeof(szObjRole));
//通过WindowFromAccessibleObject和GetClassName得到Class
GetObjectClass(*paccChild, szObjClass, sizeof(szObjClass));
//以上实现代码比较简单,大家自己看代码吧。
//如果这些参数与输入相符或输入为NULL
if ((!szName ||
!strcmp(szName, szObjName)) &&
(!szRole ||
!strcmp(szRole, szObjRole)) &&
(!szClass ||
!strcmp(szClass, szObjClass)))
*pvarChild = varC
if(!found && pCAcc)
// 以这次得到的子接口为父递归调用
found = FindChild(pCAcc,
paccChild,
pvarChild);
if(*paccChild != pCAcc)
pCAcc-&Release();
}//End for
// Clean up
pEnum -& Release();
// UI元素的状态也表示成整型形式。因为一个状态可以有多个值,
//例如可选的、可做焦点的,该整数是反映这些值的位的或操作结果。
//将这些或数转换成相应的用逗号分割的状态字符串。
UINT GetObjectState(IAccessible* pacc,
VARIANT* pvarChild,
LPTSTR lpszState,
UINT cchState)
VARIANT varRetV
*lpszState = 0;
VariantInit(&varRetVal);
hr = pacc-&get_accState(*pvarChild, &varRetVal);
if (!SUCCEEDED(hr))
return(0);
DWORD dwStateB
int cChars = 0;
if (varRetVal.vt == VT_I4)
// 根据返回的状态值生成以逗号连接的字符串。
for (dwStateBit = STATE_SYSTEM_UNAVAILABLE;
dwStateBit & STATE_SYSTEM_ALERT_HIGH;
dwStateBit &&= 1)
if (varRetVal.lVal & dwStateBit)
cChars += GetStateText(dwStateBit,
lpszState + cChars,
cchState - cChars);
*(lpszState + cChars++) = '','';
if(cChars & 1)
*(lpszState + cChars - 1) = ''\0'';
else if (varRetVal.vt == VT_BSTR)
WideCharToMultiByte(CP_ACP,
varRetVal.bstrVal,
lpszState,
VariantClear(&varRetVal);
return(lstrlen(lpszState));
好了!!我们已经成功得到文本框的 IAccessible 接口指针了!!现在你可以用这个接口指针为所欲为了!!!呵呵:)
在 IAccessible 接口上执行动作
有了表示一个可访问的 UI 元素的 IAccessible 接口/子ID对,你也有了搜索该元素一个名字(get_accName)、角色(get_accRole)、类和状态(get_accState)的方法。让我们看看你还可以干什么!get_accDescription 能取得UI元素的描述,get_accValue 能取得一个值。
最重要的函数之一是 accDoDefaultAction。每个可访问的UI元素都有一个缺省定义的动作。例如,一个按钮的缺省动作是"按下这个按钮",一个检查框的缺省动作是"不选"。为了确定一个元素的缺省动作,请参考 Active Accessibility 文档或者调用 get_accDefaultAction。
如果我想起动注册表编辑器,该怎么办呢?如果是我们手动做的话,无非是在文本输入框输入"regedit",然后按确定按钮,就这么简单。下面我们来看看用 Active Accessibility 是怎么来实现的。
//在文本输入框输入"regedit"
if(1 == FindChild (paccMainWindow, "打开(O):",
"可编辑文字",
&paccControl,
&varControl))
//在这里修改文本编辑框的值
hr = paccControl-&put_accValue(varControl,
CComBSTR("regedit"));
paccControl-&Release();
VariantClear(&varControl);
// 找到确定按钮,并执行默认动作。
if(1 == FindChild (paccMainWindow,
"按下按钮",
&paccControl,
&varControl))
//这里执行按钮的默认动作,即"按下这个按钮"
hr = paccControl-&accDoDefaultAction(varControl);
paccControl-&Release();
VariantClear(&varControl);
现在,你会发现已经成功启动了注册表编辑器!!
模拟键盘和鼠标输入
让我们假设你需要操作一个新的不完全支持 Windows 消息和 IAccessible 接口方法的 UI 元素。如果它不支持你需要的消息和方法,最简单的解决办法就是模拟键盘和鼠标输入。例如,你可以用Tab模拟转移到期望的控件。
使你能够实现这些的函数就是 SendInput 一个一般的USER API。虽然不属于Active Accessibility,把他们联合使用很自然。
SendInput 接受三个参数:要执行的鼠标键盘动作个数、INPUT结构数组和结构数组的大小。每个INPUT结构描述一个要执行的动作。注意,按下一个按钮和释放一个按钮是两个不同的动作,所以必须创建两个不同的INPUT结构。
下面的代码将模拟 ALT+F4 按键来关闭窗口。
INPUT input[4];
memset(input, 0, sizeof(input));
//设置模拟键盘输入
input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;
input[0].ki.wVk
= input[2].ki.wVk = VK_MENU;
input[1].ki.wVk
= input[3].ki.wVk = VK_F4;
// 释放按键,这非常重要
input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(4, input, sizeof(INPUT));
具体用法大家还是查MSDN吧,这里就不罗嗦了!!:)
监视WinEvents
监视 WinEvents 非常像通过 Windows Hook 监视 Windows 消息。最重要的区别就是从另一个进程监视 UI 元素发出的 WinEvents 时,你不需要创建一个单独的DLL来注入那个进程的地址空间。
监视 WinEvents 有两种选择:通过设置 SetWinEventHook 函数的最后一个参数来确定是在上下文之外还是之内监视。如果是在上下文之外,不需要额外的DLL,回调函数运行在目标进程之外。如果是在上下文之内,回调函数必须放在额外的DLL,并注入目标进程的地址空间。第二种方法写代码比较麻烦,但是运行效率高。
好,现在回到上面的例子。上面例子能够执行的前提条件是能够找到标题为"运行"的窗口。现在可以先检查运行窗口是否存在,如果不存在就设置WinEvents 钩子去监视,直到"运行"窗口被创建。看下面代码:
if(NULL == (hWndMainWindow = FindWindow(NULL, szMainTitle)))
hEventHook = SetWinEventHook(
EVENT_MIN, // eventMin ID
EVENT_MAX, // eventMax ID
// always NULL for outprocess hook
WinCreateNotifyProc,
// call back function
// idProcess
// idThread
// always the same for outproc hook
WINEVENT_SKIPOWNPROCESS | WINEVENT_OUTOFCONTEXT);
第一、二个参数用来指定监视事件的范围。第四个参数是定义的回调函数。
下面是回调函数:
void CALLBACK WinCreateNotifyProc(
HWINEVENTHOOK
dwmsEventTime
if( event != EVENT_OBJECT_CREATE)
char bufferName[256];
IAccessible *pacc=NULL;
VARIANT varC
VariantInit(&varChild);
//得到触发事件的 UI 元素的 IAccessible 接口/子ID对
HRESULT hr= AccessibleObjectFromEvent(hwndMsg,
&varChild);
if(!SUCCEEDED(hr))
VariantClear(&varChild);
//得到 UI 元素的Name,并比较,如果是"运行"就发送消息给主线程。
GetObjectName(pacc, &varChild, bufferName, sizeof(bufferName));
if(strstr(bufferName, szMainTitle))
PostThreadMessage(GetCurrentThreadId(),
WM_TARGET_WINDOW_FOUND,
恩…………,一个应用基本成型了,虽然比较简单。就先写这么多吧,请关注后续介绍。
关于IAccessible 接口/子ID对:
让我们来考虑这样一个控件,他支持 IAccessible 接口并且包含一些子控件,比如 listbox 就包含很多 items 。有两种方法让他可以被访问:第一种,提供listbox的 IAccessible 接口和每一个 item 自己的 IAccessible 接口。另一种是只提供一个控件的 IAccessible 接口,这个接口能够提供基于某种识别方法来访问每一个子控件的功能。
第一种方法,需要为这个控件和每一个子控件创建单独的 COM 对象,这会比第二种方法(每一个子控件不支持自己的 IAccessible 接口,而是通过父接口来访问)增加内存消耗。第二种方法里,通过增加一个参数--子ID--同父的IAccessible 接口一起表示这个子控件。子ID 是一个 VT_I4 型的 VARIANT 值,包含一个由程序决定的独特的值,或只是一个子控件的序号。序号意味着第一个子控件的ID为1,第二个子控件的ID为2,依次增长!
这样,如果一个子控件不支持自己的 IAccessible 接口,而其父控件支持,那么这个子控件可以用它的父控件的 IAccessible 接口/子ID 对来表示。通常,一个支持 IAccessible 接口的父UI元素也是通过这样的 IAccessible 接口/子对表示的,这时候其子ID号为 CHILDID_SELF (就是0)。
记住,子ID号总是相对于 IAccessible 接口的。例如,一个可访问的元素可以同相对于其父 IAccessible 接口的一个非子 CHILDID_SELF 的 ID 及其父IAccessible 接口表示,如果他支持 IAccessible 接口,此元素的子ID就是相对于自己 IAccessible 接口的CHILDID_SELF。
呵呵,翻译的有点别扭,意思就是说,如果这个控件支持 IAccessible 接口,那么它的子ID就是0(CHILDID_SELF),可以用它自己的 IAccessible 接口和0这个对来表示这个控件。如果控件不支持 IAccessible 接口,就用它父控件的 IAccessible 接口,和一个相对于父 IAccessible 接口的子ID来表示。哎呀!!不知道说明白没有。郁闷!!!!
我也是刚开始学习怎么使用MSAA,但是苦于很难找到中文资料。希望这篇文章对大家能有所帮助。由于了解的还很肤浅,错误难免,望谅解!!:)
还有,这篇文章基本编译自Dmitri Klementiev的《Software Driving Software: Active Accessibility-Compliant Apps Give Programmers New Tools to Manipulate Software》,只是按自己的理解重新编排了一下,如果觉得不符合自己的学习习惯可以看原文。并且我的文章省略了很多东西,呵呵。
参考资料:
1、 Dmitri Klementiev写的《Software Driving Software: Active Accessibility-Compliant Apps Give Programmers New Tools to Manipulate Software》及其源程序。/msdnmag/issues/0400/aaccess/default.aspx
2、 MSDN中的相关章节。
写的非常好,谢谢。
17:17 发表
最多还可以输入100字
【VIP年会员制套餐】
【C/C++软件工程师实战能力集训大纲】
VC知识库发布了C/C++业界的“本草纲目”
【牛人都在千人一号群! 加群三步走!!!】
第一步:请必须加VC知识库QQ: 为好友;
第二步:请必须关注本站微博:
第三步:申请加入群:.(必须将关注微博截屏发到QQ方可通过!)
【最新2013:】
全部100% VC++源码提供: E-Form++全新大型SCADA & HMI解决方案源码、CAD解决方案源码、Gis解决方案源码 、电力石油化工仿真与图形建模解决方案源码、大量其他高级制图VC++源码下载!
【 新视频发布】
o o o o o o o o o o
上回书介绍了回调接口,在此基础上,我们理解连接点就容易多了。
着好复杂呀......呵呵,其实简单的紧:(注1)
1、一个 COM 组件,允许有多个连接点对象(IConnectionPoint)。
也就是说可以有多个发生“事件”的源头。上图就有3个连接点;
2、管理这些连接点的接口叫“连接点容器”(IConnectionPointContainer)。
连接点容器接口特别简单,因为只有2个函数,一个是 FindConnectionPoint(),表示查找你想要的连接点;另一个是 EnumConnectionPoints(),表示列出所有的连接点,然后你去选择使用哪个。在实际的应用中,查找法使用最多,占90%,而枚举法使用只占 10%,一般在支持第三方的插件(Plug in)时才使用。(你想写个 IE 的插件吗?我们后面就要讲到啦)
3、每一个连接点,可以被多个客户端的接收器(Sink)连接;
这个我们已经熟悉啦,还记得我们在上回书中为了管理多个回调接口,使用了 cookie 的方式进行区别吗?!...
在VC环境中除了我们所常用的Dialog、Menu和Bitmap等标准资源类型之外,它还支持自定义资源类型(Custom Resource),我们自定义的资源类型能做些什么呢?呵呵,用处多多。...
本文介绍了套接字编程的基本知识。...请问怎么把H盘删了, 是虚拟光驱的,但我虚拟光驱已经删除了。 电脑里还是有H盘,指导下,谢谢_百度知道
请问怎么把H盘删了, 是虚拟光驱的,但我虚拟光驱已经删除了。 电脑里还是有H盘,指导下,谢谢
hiphotos.jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink"><img class="ikqb_img" src="http.<a href="/zhidao/wh%3D450%2C600/sign=54c5e6d5daa1fe13719cc//zhidao/wh%3D600%2C800/sign=4fcb4eb38bcb6256fc2e//zhidao/pic/item/f11f3a292df5e0fe7b1da85edf7228&nbsp://c://c.jpg" esrc="http://c.baidu.hiphotos
提问者采纳
重装虚拟光驱,然后卸载h再卸载虚拟光驱
解决了,那下面这个我的手机呢?
能否删除了?
我的电脑里面“我的手机”图标怎么删除
(写起来比较麻烦,这个网页很详细)
提问者评价
太给力了,你的回答完美解决了我的问题!
其他类似问题
为您推荐:
其他1条回答
即便日后你不再使用虚拟光驱,它们分别对应着虚拟光驱和物理光驱。我们动手来删除这个多余的虚拟光驱图标,重新启动电脑后虚拟光驱图标就会被删除,按下“确定”键后打开注册表编辑器,虚拟光驱图标还会继续保留,实在没有必要,输入“regedit”:单击“开始→运行”;SCSI分支当我们在系统中安装了虚拟光驱后,“我的电脑”中就会多出一个光盘图标;Enum&#92,在SCSI子键下通常有两个子键,把SCSI下的子键全部删除,依次展开HKEY_LOCAL_MACHINE&#92
没有你说的选项,怎么办
虚拟光驱的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 模拟人生4指导健身 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信