Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set Administrative right Icon on MFC Dialog Button?

Tags:

c++

c

windows

mfc

I am creating an application in MFC using Visual Studio 2008 in windows 7. My application starts and stops a service which requires administrative access. When application starts it don't have administrative access. But when I click on start service button it get the administrative access and performs the action. I am wondering how to set administrative icon on buttons whose actions need administrative access? Do I need to set some kind of Flags? Thanks

like image 435
Ali Ahmed Avatar asked Aug 23 '11 10:08

Ali Ahmed


1 Answers

As of Windows Vista you can add the shield icon to a button by using one of the new flags. There is a macro to enable it, which you can use like this:

Button_SetElevationRequiredState(hwnd, TRUE);

Documentation for the macro is at http://msdn.microsoft.com/en-us/library/bb761865%28VS.85%29.aspx

See http://msdn.microsoft.com/en-us/library/bb756990.aspx#BKMK_ShieldButton for an overview of how to do many UAC related tasks.

There is also CButton::SetElevationRequired() which presumably does the same thing but fits more in line with your MFC project. You could use it like this:

ctl->SetElevationRequired(TRUE);

See http://msdn.microsoft.com/en-us/library/bb386824%28v=VS.90%29.aspx

You also need to enable the use of the common controls v6 DLL, which you can do either using a manifest file (with or witout an entry in your resource file to embed it) or using a #pragma directive in your code for MSVC2005 or later. Chances are with an MFC application that you will already have a manifest which you can modify, but I cannot help you there as I do not have access to MFC.

If you go the manifest route it should look something like this and have the same name as your application but with ".manifest" after the .exe, e.g. MyApp.exe.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="*"
    name="CompanyName.ProductName.YourApplication"
    type="win32"
/>
<description>Your application description here.</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
</assembly>

For the #pragma, see the code below.

For more information about using v6 common controls see this link (which is where I got the above information from): http://msdn.microsoft.com/en-us/library/bb773175%28v=vs.85%29.aspx

A small win32 example which uses the pragma directive to enable common controls v6 and displays the elevation icon:

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE instance,
                    HINSTANCE previnst,
                    LPSTR args,
                    int wndState)
{
    int i;
    MSG messages;
    WNDCLASSEX wincl;
    ZeroMemory(&wincl, sizeof(wincl));
    wincl.hInstance = instance;
    wincl.lpszClassName = L"WindowsApp";
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof wincl;
    wincl.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);

    InitCommonControls();

    wincl.hIcon   = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW);

    if (!RegisterClassEx (&wincl))
        return 0;

    HWND hwnd = CreateWindow(L"WindowsApp", L"Windows App", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, instance, NULL);

    HWND hButton = CreateWindow(L"BUTTON", L"Do something", WS_TABSTOP | WS_VISIBLE | WS_CHILD, 10, 10, 200, 23, hwnd, NULL, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);

    SendMessage(hButton, WM_SETFONT, (LPARAM) GetStockObject(DEFAULT_GUI_FONT), FALSE);
    Button_SetElevationRequiredState(hButton, TRUE);

    ShowWindow(hwnd, wndState);

    while (GetMessage(&messages, NULL, 0, 0) > 0)
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
like image 131
tinman Avatar answered Sep 27 '22 21:09

tinman