Don't show me this dialog again


Man kennt ja diese Anwendungen, die einem einen Dialog zeigen mit der Option, dass dieser Dialog in Zukunft nicht mehr angezeigt werden soll. Das ist so eine Checkbox, die man anklickt und wenn man dann den Dialog schließt, dann merkt sich der Dialog die Einstellung und erscheint beim nächsten Mal nicht mehr. Hier mal ein kleiner Screenshot wie dieser Dialog aussieht:

DontShowMeThisDialogAgain

Diesen Dialog muss man gar nicht selber programmieren, da Windows in schon bereitstellt, wie auch die normale MessageBox, die man eigentlich so kennt. Eine genauere Dokumentation gibt es im MSDN SHMessageBoxCheck. Allerdings wird sie anscheinend nicht mit ihrem Namen exportiert, sondern nur über ihren Index. Laut Raymond Chen wird sie nur über ihren Index exportiert, weil sie nur für den internen Gebrauch bestimmt war:

because it was an internal function in xp - never intended for public use (notice all the bugs in the function as listd in the documentation)
[..]
all internal callers were aware of the bugs and knew to avoid them

Die Funtionsweise ist recht simpel. Markiert man die Checkbox und schließt den Dialog, wird ein Wert in die Registry geschrieben, an Hand dessen Windows dann merkt, ob diese MessageBox angezeigt werden soll oder nicht. Hier mal die Delphi Deklaration der entsprechenden API Funktion MessageBoxCheck:

function MessageBoxCheck(hWnd: THandle; Text: PChar; Title: PChar; dwType: DWORD; Default: Integer;
  RegVal: PChar): Integer; stdcall;

Da sie natürlcih auch in keiner Borland Unit deklariert ist, muss man sie noch aus der entsprechenden DLL laden:

function MessageBoxCheck; external 'shlwapi.dll' index 185;

Wie man sieht, wird sie nur über ihren Index exportiert und nicht, wie es sonst üblich ist, über ihren Namen. Ein Beispielaufruf unter Delphi könnte dann so aussehen:

function MessageBoxCheck(hWnd: THandle; Text: PChar; Title: PChar; dwType: DWORD; Default: Integer;
  RegVal: PChar): Integer; stdcall;

implementation

{$R *.dfm}

function MessageBoxCheck; external 'shlwapi.dll' index 185;

procedure TForm1.Button1Click(Sender: TObject);
const
  REGVALUE = 'Demo';
begin
  MessageBoxCheck(Handle, 'Irgendein Text', 'Titel', MB_YESNO or MB_ICONWARNING, 0, REGVALUE);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Caption := 'DontShowMeThisDialogAgain';
end;

Aber wie immer bei undokumentierten Funktionen, sollte man diese mit Vorsicht geniessen. Im nächsten Servicepack kann sich Microsoft schon dafür entschieden haben, sie wieder rauszunehmen oder ihre Parameterliste zu ändern oder ihren Index in der DLL zu ändern oder sie könnte gar nicht mehr vorhanden sein. Also wenn man sie benutzt, dann sollte man sie auch immer vorher unter allen aktuellen Betriebssystemen von Microsoft ausgiebig testen. Allerdings hatte ich bisher unter Windows 2000 SP4 und unter Windows XP Home/Professional SP2 keinerlei Probleme.

Aber worauf ich eigentlich hinaus wollt, ist was ganz anderes. Wie schon gesagt, legt Windows in der Registry einen Wert ab, um zu entscheiden, ob der Dialog wieder angezeigt werden soll oder nicht. Dieser Wert befindet sich im Schlüssel:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain

Bemerkenswert fand ich den Namen des Schlüssels: "DontShowMeThisDialogAgain". Sonst ist man ja nur so kryptische Schlüsselbezeichnungen in der Registry gewohnt, die meist auch noch recht kurz sind. Aber diese ist ja gerade zu selbst redent und noch dazu sehr lang. Anscheinend ist dem Programmierer wirklich nichts kürzeres eingefallen.

2010-12-29T23:44:43 +0100, mail+homepage[at]michael-puff.de