Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add the UAC shield icon to the standard messagebox?

I want to notify the user that my application wants to start an elevated process using the standard MessageBox. Is there a way of achieving this short of reimplementing the MessageBox?

For example, for standard buttons, you can send the BCM_SETSHIELD message. Is there something similar for message boxes?

like image 973
Yngve Hammersland Avatar asked Mar 18 '11 10:03

Yngve Hammersland


2 Answers

In order to get the shield icon onto the buttons of a system provided message dialog you are going to need to handle a callback from the dialog.

For example, I will illustrate with the TaskDialogIndirect() API introduced in Vista.

The basic dialog allows you to specify the main icon, but not the shield icon for the buttons on the dialog. To do this you need to provide a callback function that responds to the TDN_CREATED notification.

That callback might look like this:

HRESULT CALLBACK TaskDialogCallbackProc(
    HWND hwnd,
    UINT uNotification,
    WPARAM wParam,
    LPARAM lParam,
    LONG_PTR dwRefData
)
{
   if (TDN_CREATED == uNotification)
   {
       SendMessage(
           hwnd,
           TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE,
           ID_FOR_MY_BUTTON_SPECIFIED_IN_TASKDIALOGCONFIG_STRUCT,
           1
       );
   }
   return S_OK;
}

The magic is contained in the TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE message.

As far as I can tell, this is the way you are intended to achieve the effect you desire.

like image 81
David Heffernan Avatar answered Nov 03 '22 00:11

David Heffernan


Buttons in a message dialog are standard buttons, you can send them a BCM_SETSHIELD message.

For this, you need to be aware when a message dialog box is activated. One way can be to set a temporary WH_CBT hook and in its callback watch for an 'nCode' of HCBT_ACTIVATE for a window having the dialog class (#32770).

Another way can be to handle WM_ACTIVATE after 'MessageBox' is called, 'wParam' should be WA_ACTIVE and 'lParam' should be a window handle again of the dialog class. Then you can send the 'BCM_SETSHIELD' message to the button f.i. having control id IDOK.

messsage box with shielded button

like image 33
Sertac Akyuz Avatar answered Nov 03 '22 01:11

Sertac Akyuz