Today I reused a unit I wrote a long time ago for TSAdminEx that shows Resource Dialogs from DLL’s or Executables. I wrote it for a couple of reasons:

  • Reusing existing dialogs is conventient since the user already knows it.
  • Windows takes care of translating it into the user’s language.
  • I am too lazy to recreate them ;-)

The code is hardly rocket science and could probably be improved and made more sophisticated but it works for me. I decided to share it since you may find it usefull.

Here is a small usage example that shows the Reset Password dialog from Active Directory Users & Computers. This dialog is in dsadmin.dll (on Windows Vista/7 you will find it in ds.admin.dll.mui in the language subfolder eg %systemroot%\system32\en-US but you can load it using just the dll name).

It looks like this:

215 DIALOGEX 0, 0, 252, 139
STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "Reset Password"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
FONT 8, "MS Shell Dlg"
{
   CONTROL "&New password:", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 10, 79, 10
   CONTROL "", 220, EDIT, ES_LEFT | ES_PASSWORD | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 92, 7, 153, 14
   CONTROL "&Confirm password:", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 28, 79, 10
   CONTROL "", 222, EDIT, ES_LEFT | ES_PASSWORD | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 92, 25, 153, 14
   CONTROL "&User must change password at next logon", 261, BUTTON, BS_AUTOCHECKBOX | BS_LEFT | BS_TOP | BS_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 46, 237, 10
   CONTROL "The user must logoff and then logon again for the change to take effect.", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 14, 61, 231, 8
   CONTROL "", 8327, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 76, 238, 16
   CONTROL "Unlock the user’s &account", 8328, BUTTON, BS_AUTOCHECKBOX | BS_LEFT | BS_TOP | BS_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 14, 96, 230, 10
   CONTROL "OK", 1, BUTTON, BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 140, 118, 50, 14
   CONTROL "Cancel", 2, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 195, 118, 50, 14
}
 

The code to display it in Delphi looks like this:

procedure TMainForm.ChangePasswordExecute(Sender: TObject);
const
  NewPasswordId = 220;
  ConfirmPasswordId = 222;
var
  ResDialog: TResDialog;
  NewPassword: TResControl;
  ConfirmPassword: TResControl;
begin
  ResDialog := TResDialog.Create(Handle, ‘dsadmin.dll’, 215, InitChangePassword);
  NewPassword := ResDialog.Controls.FindByResourceId(NewPasswordId);
  ConfirmPassword := ResDialog.Controls.FindByResourceId(ConfirmPasswordId);

  if Assigned(NewPassword) and Assigned(ConfirmPassword) then
  begin
    ShowMessageFmt(‘New Password = %s Confirm Password =%s’, [NewPassword.Text, ConfirmPassword.Text]);
  end;

  ResDialog.Free;
end;

The Constructor takes the following parameters:

  • Parent Window Handle
  • DLL or Exe name
  • Dialog Resource Id
  • Optional: A procedure that is called before displaying the dialog where you can init the controls.

My init procedure looks like this:

procedure InitChangePassword(ResourceControlListPtr: PResControls);
const
  MustChangeId = 261;
  UnlockId = 8328;
var
  MustChange: TResControl;
  Unlock: TResControl;
begin
  MustChange := ResourceControlListPtr^.FindByResourceId(MustChangeId);
  if Assigned(MustChange) then
  begin
    MustChange.Checked := True;
  end;
  Unlock := ResourceControlListPtr^.FindByResourceId(UnlockId);
  if Assigned(Unlock) then
  begin
    Unlock.Checked := True;
  end;
end;

ResetPassword

Have fun with it and if you improve something please let me know!

ResDialogs (97)

Related posts:

  1. Working with bitfields in Delphi
  2. Reading accountExpires attribute from Active Directory (in Delphi)