api应用简介2

 1、自动打开“我的电脑”

     我的问题是在Win95 or Win98 下,能不能编一个程序实现这样的功能. 该程序先自动打开“我的电脑”, 然后在自动关闭, 然后在模拟按键Alt+F4出现关机界面, 最后在模拟输入"Alt+y"关闭计算机。 能实现的话,如何实现?采用的语言为vc++ 5.0 。谢谢!(wenwp01) 
   
     可以使用SHGetSpecialFolderLocation函数获得“我的电脑”所对应的虚拟文件夹的id。然后使用ShellExecuteEx打开这个虚拟文件夹。
    使用API函数SHGetSpecialFolderLocation。shlobj.h里有SHGetSpecialFolderLocation的原型声明。这个函数可以帮我们找到Windows的桌面目录、启动目录、我的文档目录等。
    SHGetSpecialFolder需要三个参数。 第一个参数是HWND,它指定了"所有者窗口":在调用这个函数时可能出现的对话框或消息框。第二个参数是一个整数id,决定哪个目录是待查找目录,它的取值可能是:
     CSIDL_BITBUCKET 回收站
CSIDL_CONTROLS 控制面板
CSIDL_DESKTOP Windows 桌面Desktop
CSIDL_DESKTOPDIRECTORY Desktop的目录
CSIDL_DRIVES 我的电脑
CSIDL_FONTS 字体目录
CSIDL_NETHOOD 网上邻居
CSIDL_NETWORK 网上邻居虚拟目录
CSIDL_PERSONAL 我的文档
CSIDL_PRINTERS 打印机
CSIDL_PROGRAMS 程序组
CSIDL_RECENT 最近打开的文档
CSIDL_SENDTO “发送到”菜单项
CSIDL_STARTMENU 任务条启动菜单项
CSIDL_STARTUP 启动目录
CSIDL_TEMPLATES 文档模板

    这里只是最常用的部分。完整的请参考http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp
    最后一个参数是pidl地址。SHGetSpecialFolderLocation把地址写到pidl。
    下面是一个例子:
    LPITEMIDLIST pidl;
    TCHAR szPath [MAX_PATH];
    LPMALLOC pMalloc;
    
    if ( SUCCEEDED( SHGetSpecialFolderLocation ( NULL, CSIDL_DRIVES, &pidl )))
    {
     SHELLEXECUTEINFO sei;
     ZeroMemory(&sei, sizeof(sei));
     sei.cbSize = sizeof(sei);
     sei.fMask = SEE_MASK_IDLIST;
     sei.lpIDList = pidl;
     sei.lpVerb = "open";
     sei.hwnd = AfxGetMainWnd()->GetSafeHwnd();
     sei.nShow = SW_SHOWNORMAL;
     ShellExecuteEx(&sei);
     if ( SUCCEEDED( SHGetMalloc ( &pMalloc )))
     {
     pMalloc->Free ( pidl );
     pMalloc->Release();
     }
    }
    
    由于“我的电脑”是虚拟文件夹,所以必须使用ShellExecuteEx函数,如果是普通文件夹,则可以使用SHGetPathFromIDList获得文件名,然后利用ShellExecute函数打开。例如要打开“发送到”文件夹,可以这样:
    if ( SUCCEEDED( SHGetSpecialFolderLocation ( NULL, CSIDL_SENDTO, &pidl )))
    {
     if ( SHGetPathFromIDList ( pidl, szPath ))
     {
     ShellExecute(AfxGetMainWnd()->GetSafeHwnd(),
     "open", szPath, NULL, NULL,
     SW_SHOWNORMAL);
     }
    
     if ( SUCCEEDED( SHGetMalloc ( &pMalloc )))
     {
     pMalloc->Free ( pidl );
     pMalloc->Release();
     }
    }
    
    
    如果是虚拟文件夹,SHGetPathFromIDList函数会失败。
    对于普通文件夹也可以使用SHGetSpecialFolderPath函数,而不使用SHGetSpecialFolderLocation函数,这样更简单些,但运行环境必须是Windows 2000以后的操作系统或安装了IE 4.0以上版本。
    关闭窗口和关机参考QA000166 "如何利用VB实现操作系统或者某一应用程序的自动关闭"。
    
***************************************************
 2、如何使我的进程有超级用户的权限

    问题:我想利用
     hThread = OpenThread(THREAD_TERMINATE, FALSE, dwThreadid);//te32.th32ThreadID);
     Re = GetLastError();
    
    来停止一个知道了线程ID号的线程,但总是返回错误号5(Access is denied)
    是我的进程的权限不够,能告诉我如何使我的进程有超级用户的权限,谢谢! 
   
     li_xf的意见:
    首先使用LogonUser函数创建一个token.
    根据调用参数,有可能需要调用 DuplicateTokenEx 函数,将impersonation token 转换为a primary token.
    
    然后使用这个token 调用CreateProcessAsUser函数,创建一个拥有该用户安全上下文(context)的进程.
    (具体例子详见MSDN)
    
    函数原型:
    BOOL LogonUser(
     LPTSTR lpszUsername,
     LPTSTR lpszDomain,
     LPTSTR lpszPassword,
     DWORD dwLogonType,
     DWORD dwLogonProvider,
     PHANDLE phToken
    );
    BOOL CreateProcessAsUser(
     HANDLE hToken,
     LPCTSTR lpApplicationName,
     LPTSTR lpCommandLine,
     LPSECURITY_ATTRIBUTES lpProcessAttributes,
     LPSECURITY_ATTRIBUTES lpThreadAttributes,
     BOOL bInheritHandles,
     DWORD dwCreationFlags,
     LPVOID lpEnvironment,
     LPCTSTR lpCurrentDirectory,
     LPSTARTUPINFO lpStartupInfo,
     LPPROCESS_INFORMATION lpProcessInformation
    );
    BOOL DuplicateTokenEx(
     HANDLE hExistingToken,
     DWORD dwDesiredAccess,
     LPSECURITY_ATTRIBUTES lpTokenAttributes,
     SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
     TOKEN_TYPE TokenType,
     PHANDLE phNewToken
    );
    
 ************************************************
3、GetTickCount()函数精确到多少毫秒
GetTickCount()和GetCurrentTime()都只精确到55ms(1个tick就是55ms)。如果要精确到毫秒,应该使用timeGetTime函数或QueryPerformanceCounter函数。具体例子可以参考QA001022 "VC++中使用高精度定时器"、QA001813 "如何在Windows实现准确的定时"和QA004842 "timeGetTime函数延时不准"。
 
*************************************************
4、如何用VB或VC对Win 95及NT的注册文件进行读写
 Win 95及NT的注册数据库(Registry)是系统中非常重要的组成部分。在Win32 API中有一组Reg函数来处理这些问题。其一般的读写过程如下:
    1、使用RegOpenKeyEx或RegCreateKeyEx函数打开或创建一个键;
    2、如果上一步成功,使用RegQueryValueEx读取子键的值,使用RegSetValueEx设置子键值,使用RegEnumKey获得所有子键,使用RegDeleteKey删除一个键;
    3、完成操作后使用RegCloseKey关闭键。
    下面这段程序打开HKEY_CURRENT_USER\Software\Zeal SoftStudio\AskPro FTP\LastTime键,然后读取WOL子键的值。
     HKEY hkey;
     char sz[256];
     DWORD dwtype, sl = 256;
    
     RegOpenKeyEx(HKEY_CURRENT_USER,
     "Software\\Zeal SoftStudio\\AskPro FTP\\LastTime",
     NULL, KEY_ALL_ACCESS, &hkey);
     RegQueryValueEx(hkey, "WOL", NULL, &dwtype, (LPBYTE)sz, &sl);
     RegCloseKey(hkey);
    
    MFC程序可以使用CRegKey类读写注册表。
    VB中调用API的办法可以参考QA000226 "如何访问Windows系统注册表"。
    
*************************************************
5、回调函数的内在机制如何
    编程工具: C++ BUILDER 3.0
    操作系统: WIN98
    我想在C++ 中使用回调函数,请问它的内在机制如何,另外怎么定义。我用DialogBox函数时,如何使用回调函数? 它和钩子函数有何不同?多谢指教!!!拜托!!!

A回答:

    使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。至于如何定义回调函数,跟具体使用的API函数有关,一般在帮助中有说明回调函数的参数和返回值等。C++中一般要求在回调函数前加CALLBACK,这主要是说明该函数的调用方式。DialogBox的回调函数实际上是个窗口过程,用来处理所有消息。其定义为:
    BOOL CALLBACK DialogProc(
    
     HWND hwndDlg, // handle of dialog box
     UINT uMsg, // message
     WPARAM wParam, // first message parameter
     LPARAM lParam // second message parameter
     );
    在Win32 API中有详细说明。一般使用C++ Builder或MFC的往往没有使用SDK编程的经验,建议找一些SDK编程的书看一下,否则很难理解如何使用窗口过程。
    至于钩子函数,只是回调函数的一个特例。习惯上把与SetWindowsHookEx函数一起使用的回调函数称为钩子函数。也有人把利用VirtualQueryEx安装的函数称为钩子函数,不过这种叫法不太流行。
    
    frank的意见:
    我对回调函数的理解虽然粗浅,但是我觉得会让人更容易理解:回调函数就相当于一个中断处理函数,由系统在符合你设定的条件时自动调用。为此,你需要做三件事:1,声明;2,定义;3,设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于系统调用。
    声明和定义时应注意:回调函数由系统调用,所以可以认为它属于WINDOWS系统。不要把它当作你的某个类的成员函数。
    
    ping的意见:
    frank说:回调函数属于WINDOWS系统。我觉得不应该说回调函数是属于系统的。应该说是程序把这段代码的触发交由系统来做。而这种做法是WINDOWS提供的处理机制吧,因为消息是系统一手掌握着的,由系统来调用我们的程序对消息的处理部分,这样子会比较方便。不然我们又得花力气去读消息列表了。(不知道我说的对不对,接触系统还不深,请高手指教哦)

 *************************************************
6、如何获得其他运行的应用程序发出的消息

如何获得其他运行的应用程序发出的消息?

回答:

    一般是利用API函数SetWindowsHookEx来建立钩子函数,这样Windows在处理消息之前会将消息传递给钩子函数。Windows截取消息分为两种:线程和系统。线程方式只能截取当前线程消息,而系统方式可以获得所有消息。如果要实现系统方式,需要调用API函数SetWindowsHookEx,如:
    SetWindowsHookEx(WH_MOUSE, MyHooProc, 0, 0);
    但这种方式必须编写一个标准DLL。
    在VC++中有一个Spy的例子(在MSDN\Samples\VC98\sdk\sdktools\spy\目录),它的具体功能就是Spy++的工作,你可以参考。
    另外,可以参考QA000888

"怎样使用钩子函数"。

***********************************************
 
在Win32 API中有详细的关于钩子函数的介绍,如果你没有Win32 API,可以参考QA000150 "哪里能够找到WIN95 API的资料"。
    Windows的钩子函数分两种,一种是全局的,一种是线程的。全局的钩子函数可以捕获任何应用程序的消息,但必须是标准的DLL才能实现,VB做不了。VB可以实现线程的,就是当前应用程序的消息,这对鼠标消息的捕捉有影响。
    SetWindowsHookEx定义如下:
    Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
    idHook是钩子类型,如WH_KEYBOARD捕捉键盘消息,而WH_MOUSE捕捉鼠标消息。hmod用于全局钩子,VB要实现钩子,必须设为0。dwThreadId用于线程钩子VB中可以设置为App.ThreadID。lpfn为钩子函数,在VB中可以使用AddressOf获得钩子函数的地址。这个函数因为钩子类型不同而有所不同。如键盘钩子为:
    Public Function KeyboardProc(ByVal nCode As Long, _
     ByVal wParam As Long, _
     ByVal lParam As Long) As Long
    如果Code不为0,钩子函数必须调用CallNextHookEx,将消息传递给下面的钩子。wParam和lParam不是按键。
    你可以在微软的Knowledge Base的文章:“Q180936 OWTO: Position a MsgBox Using a Windows Hook Procedure”、微软的Knowledge Base的文章:“Q177992 OWTO: Intercept Keyboard Input from Visual Basic”和找到VB使用钩子函数的例子。

转载于:https://www.cnblogs.com/qiyuan/archive/2005/05/24/161304.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值