您好,欢迎来到宝玛科技网。
搜索
您的当前位置:首页Windows 7 taskbar and startmenu pin

Windows 7 taskbar and startmenu pin

来源:宝玛科技网

在Windows 7上,用户可以将自己喜欢的软件“钉”在开始菜单或任务栏,使用起来更加方便。但有时候我们也需要用程序来将这个过程自动化,比如在IT环境里定制客户机,或者我们从一台Win7系统迁移到另一台Win7系统时。

怎么知道已有哪些软件被“钉”在开始菜单或任务栏:

如何把软件“钉”在开始菜单或任务栏:

需要注意的是只能将链接钉在开始菜单或任务栏,而且链接必须指向可执行程序,所以我们需要先为目标程序创建一个链接,然后调用ShellExecute,将链接钉住,钉完后这个链接可以删掉。任务栏上钉与解除时传递给ShellExecute的lpOperation参数是taskbarpin/taskbarunpin,而开始菜单的lpOperation参数是startpin/startunpin。

示例,将IE钉在任务栏上:

1. 在桌面上为IE创建链接IE.lnk

2. ShellExecute(NULL, "taskbarpin", "c:\users\username\Desktop\IE.lnk", NULL, NULL, 0)

以上有一个,就是不知道在任务栏上链接的顺序。

 

Windows XP 任务栏的遍历

2009-05-04 9:26

    这里的方法可以找到XP下的任务栏,并对任务栏进行遍历,在其他系统上就需要相应的改动了。这里是先找到ToolbarWindow32这个窗口,然后再用通用的遍历Toolbar的方法查找各个按钮;这里有一点特别的是,要用到跨进程缓冲区(因为任务栏和遍历程序不是在同一个进程)。
    在XP下有一个“分组相似任务栏按钮”特性,如果有一个新的进程窗口要在任务栏上显示,则系统会创建两个按钮,一个按钮有BTNS_DROPDOWN style,默认隐藏,在任务分组后显示(这个style指定它显示一个箭头图标);另一个按钮就是通常我们看到的任务栏按钮。
    struct TBBUTTONDATA是从网上找到的,没有在微软的文档中发现,但在XP上验证是有效的。
    在遍历按钮,SendMessage的时候,要注意是Zero-based index 还是 Command ID,现在一些网上的资料范例在需要传Command ID的时候传Zero-based index做参数,这是错误的。
HWND GetTaskButtonHost(HWND hShellTrayWnd)
{
    HWND hWnd = FindWindowEx(hShellTrayWnd, NULL, _T("ReBarWindow32"), NULL);
    if (hWnd == NULL)
        return FALSE;
    hWnd = FindWindowEx(hWnd, NULL, _T("MSTaskSwWClass"), NULL);
    if (hWnd == NULL)
        return FALSE;
    hWnd = FindWindowEx(hWnd, NULL, _T("ToolbarWindow32"), NULL);
    return hWnd;
}
//MSDN: To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE.
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    TCHAR strClsName[MAX_PATH+1] = _T("");
    GetClassName(hwnd, strClsName, MAX_PATH+1);
    if (_tcsicmp(strClsName, _T("Shell_TrayWnd")) == 0)
    {
        HWND hShellTrayWnd = GetTaskButtonHost(hwnd);
        if (hShellTrayWnd)
        {
            HWND *pHwnd = (HWND *)lParam;
            *pHwnd = hShellTrayWnd;
            return FALSE;
        }
    }
    return TRUE;
}
struct TBBUTTONDATA
{
    HWND hwnd; //the handle of the window on the taskbar
    UINT uID;
    UINT uCallbackMessage;
    DWORD Reserved[2];
    HICON hIcon;
};
//This solution works on XP.
void EnumTasks()
{
    HWND hWnd = NULL;
    EnumWindows(EnumWindowsProc, (LPARAM)&hWnd);
    if (hWnd == NULL)
        return;
    DWORD dwProcID = 0;
    GetWindowThreadProcessId(hWnd, &dwProcID);
    HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcID);
    if (hProcess == NULL)
        return;
    LPTSTR pProcBuf = NULL; //pointer to the buffer allocated in another process
    TBBUTTON tbb;
    TBBUTTONDATA tbbData;
    TCHAR strCaption[MAX_PATH+1] = _T("");
    pProcBuf = (LPTSTR)VirtualAllocEx(hProcess, NULL, sizeof(strCaption), MEM_COMMIT, PAGE_READWRITE);
    if (pProcBuf == NULL)
    {
        CloseHandle(hProcess);
        return;
    }
    DWORD nTaskCount = ::SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);
    for (DWORD i = 0; i < nTaskCount; i++)
    {
        ZeroMemory(&tbb, sizeof(TBBUTTON));
        WriteProcessMemory(hProcess, pProcBuf, &tbb, sizeof(TBBUTTON), NULL);
        SendMessage(hWnd, TB_GETBUTTON, i/*Zero-based index*/, (LPARAM)pProcBuf);
        ReadProcessMemory(hProcess, pProcBuf, &tbb, sizeof(TBBUTTON), NULL);
        //Group similar task-bar buttons(a feature of Windows): if the top-level window is
        //shown on task-bar, Windows will create another dropdown button for each process.
        if (tbb.fsStyle & BTNS_DROPDOWN)
            continue;
        ReadProcessMemory(hProcess, (LPCVOID)tbb.dwData, &tbbData, sizeof(TBBUTTONDATA), NULL);
        DWORD nDesireLen = SendMessage(hWnd, TB_GETBUTTONTEXT, tbb.idCommand, 0); //length not including null terminator
        if (nDesireLen >= sizeof(strCaption))
            continue;
        ZeroMemory(strCaption, sizeof(strCaption));
        WriteProcessMemory(hProcess, pProcBuf, strCaption, sizeof(strCaption), NULL);
        SendMessage(hWnd, TB_GETBUTTONTEXT, tbb.idCommand, (LPARAM)pProcBuf);
        ReadProcessMemory(hProcess, pProcBuf, strCaption, sizeof(strCaption), NULL);
        OutputDebugInfo(L"%s\n", strCaption);
    }
    VirtualFreeEx(hProcess, pProcBuf, 0, MEM_RELEASE);
    CloseHandle(hProcess);
}

 

前一篇介绍了在XP下遍历任务栏的方法,可以精确遍历出任务栏的按钮;这篇博客介绍一种通用的遍历任务栏的方法(不仅限于XP),但可能结果不是太精确。
对于什么样的窗口才会在任务栏上创建按钮,MSDN上的说法是:

The Shell creates a button on the taskbar whenever an application creates a window that isn't owned. To ensure that the window button is placed on the taskbar, create an unowned window with the WS_EX_APPWINDOW extended style. To prevent the window button from being placed on the taskbar, create the unowned window with the WS_EX_TOOLWINDOW extended style. As an alternative, you can create a hidden window and make this hidden window the owner of your visible window.

做了一些测试,总结的结果是:

1、如果窗口没有被其他窗口拥有(GetWindow(hwnd, GW_OWNER) == 0),那么默认情况下它会在任务栏中创建按钮,除非:

a). 窗口被隐藏了

或者:

b). 窗口有WS_EX_TOOLWINDOW风格,且没有WS_EX_APPWINDOW风格

2、如果窗口被其他窗口拥有,默认不会在任务栏创建按钮,除非:

a). 窗口可见,且有WS_EX_APPWINDOW风格

从1、2点可以得出结论,如果窗口可见,有WS_EX_APPWINDOW和WS_EX_TOOLWINDOW风格,那么,这个窗口是一个Tool window,且在任务栏上有按钮。

范例:

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    LONG lExStyle = ::GetWindowLong(hwnd, GWL_EXSTYLE);
    if (::IsWindowVisible(hwnd) &&
        ( (lExStyle & WS_EX_APPWINDOW) ||
          (GetWindow(hwnd, GW_OWNER) == NULL && (lExStyle & WS_EX_TOOLWINDOW) == 0) )
        )
    {
        TCHAR strTitle[MAX_PATH+1] = _T("");
        GetWindowText(hwnd, strTitle, MAX_PATH+1);
        OutputDebugInfo(L"%s\n", strTitle);
    }
    return TRUE;
}
EnumWindows(EnumWindowsProc, NULL);

 

 

 

 

Vista UAC : 以管理员权限运行程序

2009-04-25 20:21

在Windows Vista启用UAC后,程序启动后默认没有管理员权限,

C/C++, 可调用ShellExecute或ShellExecuteEx, 把lpOperation/lpVerb设成"RunAs"就可以

二、从开发人员角度:
1、在应用程序RC中加入MANIFEST类型资源.
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0">
<trustinfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedprivileges>
<requestedexecutionlevel level="requireAdministrator" uiaccess="false">
</requestedexecutionlevel>
</requestedprivileges>
</security>
</trustinfo>
2、以上几种方法都使得程序刚运行就要求管理员权限,要在程序运行中动态要求管理员权限则可以使用COM Elevation Moniker。可参考:

转载于:https://www.cnblogs.com/ququer/archive/2012/02/27/2370039.html

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- baomayou.com 版权所有 赣ICP备2024042794号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务