Undocumented
Windows ® 95
Shell Common Dialogs
T he common dialogs provided in COMDLG32.DLL can be
immensely useful, but they don't cover every situation.
xxxxxxxxxxxxxxx
There are plenty of other system dialogs that you may need
to use, and trying to duplicate the exact same interface can
be extremely frustrating and time consuming.
      In this article I'll be revealing a few of the undocumen-
ted dialogs provided by the shell that you can use in your
own applications. They're all exported from SHELL32.DLL
and, like most undocumented functions, they're all exported
by ordinal.
Choosing Icons
The first function I'll be discussing is PickIconDlg. Ob-
viously enough, it provides an interface with which the user
can select an icon. It's used by the file type editor when
selecting the icon to associate with a particular file type. It's
also used in the shortcut properties dialog when changing
the icon. The ordinal value is 62, and the function declara-
tion looks like this:
   BOOL WINAPI PickIconDlg(
     HWND     hwndOwner, 
     LPSTR    lpstrFile, 
     DWORD    nMaxFile, 
     LPDWORD  lpdwIconIndex);
      hwndOwner identifies the window that owns the dialog
box. lpstrFile points to a buffer containing the initial file-
name. When the function returns, this buffer will contain
the new filename. nMaxFile specifies the size, in charac-
ters, of the buffer. lpdwIconIndex points to a variable con-
taining the zero based offset of the icon. When the function
returns, the variable will be set to the new icon index.
      If the user selects an icon, the return value is TRUE. It
is FALSE if the user chooses the Cancel button, or the Close
command on the System menu. 
Running Applications
The next function, RunFileDlg, is probably not as useful, but
still warants mentioning since it is amazingly flexible. It is
the dialog that you see when launching applications from
the Start/Run menu. The ordinal value is 61 and the
function declaration looks like this:
   void WINAPI RunFileDlg(
     HWND    hwndOwner, 
     HICON   hIcon, 
     LPCSTR  lpstrDirectory, 
     LPCSTR  lpstrTitle, 
     LPCSTR  lpstrDescription,
     UINT    uFlags);
      hwndOwner identifies the window that owns the dialog
box. hIcon is the handle of the icon that will be displayed in
the dialog. If it is NULL, the default icon will be used. lpstr-
Directory points to a string that specifies the working direc-
tory. lpstrTitle points to a string to be placed in the title bar
of the dialog box. If
it is NULL, the de-
fault title is used.
lpstrDescription
points to a string
that is displayed in
the dialog, briefly in-
forming the user
what to do. If it is
NULL, the default
description is used.
uFlags is a set of bit
flags that specify
RFF_NOBROWSE 0x01 Removes the browse
button.
RFF_NODEFAULT 0x02 No default item selected.
RFF_CALCDIRECTORY 0x04 Calculates the working
directory from the file name.
RFF_NOLABEL 0x08 Removes the edit box label.
RFF_NOSEPARATEMEM 0x20 Removes the Separate
Memory Space check box
(Windows NT only).
Figure 1  RunFileDlg Flags
other properties of the dialog. The full list of flags is shown
in Figure 1.
      A nice feature of this dialog is that it al-
lows you to control which applications the
user may run. When the user selects the OK
button, your parent window is sent a notifica-
tion with details of the program that is about
to be started. The notification is in the form
of a WM_NOTIFY message with the notifica-
tion code set to RFN_VALIDATE (-510) and
the lParam pointing to an NM_RUNFILEDLG
typedef struct {
  NMHDR   hdr;
  LPCSTR  lpFile;
  LPCSTR  lpDirectory; 
  int     nShow;
} NM_RUNFILEDLG;
Figure 2  Notification Structure
structure (the structure definition can be seen in Figure 2).
The return value deter-
mines whether the appli-
cation will be run or not
(see Figure 3 for the full
list).
RF_OK 0x00 Allow the application to run.
RF_CANCEL 0x01 Cancel the operation and close the
dialog.
RF_RETRY 0x02 Cancel the operation, but leave the
dialog open.
Figure 3  Notification Return Values
Shutting Down the
System
The next two functions, ExitWindowsDialog and Restart-
Dialog, both deal with the problem of shutting down and
restarting the operating system. They may seem out of
place in this section, since they're not really much more
than extensions of the ExitWindowsEx function, but they do
both produce dialogs as part of the process. The ordinal
value for ExitWindowDialog is 60, the ordinal for Restart-
Dialog is 59. The function declarations look like this:
   void WINAPI ExitWindowsDialog(
     HWND hwndOwner);
   
   int WINAPI RestartDialog(
     HWND    hwndOwner, 
     LPCSTR  lpstrReason, 
     UINT    uFlags);
      ExitWindowsDialog is probably the least useful of the
two. It is the dialog that is displayed when you select Shut
Down from the Start menu. The dialog never actually uses
hwndOwner as a parent. On Windows 95, hwndOwner will
receive a WM_QUIT message if the operation is successful.
On Windows NT, the window doesn't appear to be used at
all. There is no return value for the function, so you have no
way of knowing what the user selected or whether the
operation was canceled.
      RestartDialog is used when changes are made to the
system that require a shutdown or restart be-
fore they can take effect. hwndOwner identi-
fies the owner window. lpstrReason points to
a string that is displayed in the dialog explai-
ning the reason for the shutdown. uFlags spe-
cifies the type of shutdown - you can use a
subset of the flags used by ExitWindowsEx
(see Figure 4). The return value is IDYES if the
user choose to perform the shutdown. It is
IDNO if the operation was canceled.
      There are a couple of other points you
EWX_LOGOFF 0x00
EWX_SHUTDOWN 0x01
EWX_REBOOT 0x02
EW_RESTARTWINDOWS 0x42
EW_REBOOTSYSTEM 0x43
EW_EXITANDEXECAPP 0x44
Figure 4  RestartDialog Flags
should note. The reason displayed in the dialog always has
some default text appended to it asking the user to confirm
the operation. It is therefore advisable that you always end
your reason with a space or a newline. The title of the
dialog is always set to 'System Settings Change'. The return
value can not be used to determine the success of the ope-
ration. If the operation failed for some reason, the return
value will still be IDYES.
Browsing for Files
There really isn't any reason why you should have to use
this next function. GetFileNameFromBrowse is nothing
more than a simplified wrapper around the GetOpenFile-
Name function. However, it is nice to be able to browse for
a file with a single function call, without the tedious process
of filling in all the members of the OPENFILENAME struc-
ture. The ordinal value is 63 and the function declaration
looks like this: 
   BOOL WINAPI GetFileNameFromBrowse(
     HWND    hwndOwner, 
     LPSTR   lpstrFile, 
     DWORD   nMaxFile, 
     LPCSTR  lpstrInitialDir, 
     LPCSTR  lpstrDefExt, 
     LPCSTR  lpstrFilter, 
     LPCSTR  lpstrTitle);
      Most of the parameters to this function correspond
directly with members of the OPENFILENAME structure.
hwndOwner identifies the window that owns the dialog
box. lpstrFile points to a buffer that contains a filename
used to initialize the edit control. When the function returns,
this buffer contains the full path of the selected file. nMax-
File specifies the size, in characters, of the buffer pointed to
by lpstrFile. 
      lpstrInitialDir points to a string that specifies the initial
file directory. If lpstrFile contains an initial filename, the
lpstrInitialDir is ignored and the path from the filename is
used instead. lpstrDefExt points to a buffer that contains
the default extension. lpstrFilter points to a buffer contai-
ning pairs of null-terminated filter strings. lpstrTitle points to
a string to be placed in the title bar of the dialog box. See
the documentation on OPENFILENAME for more details. 
      If the user selects a file to open, the return value is
TRUE. It is FALSE if an error occurs, the user chooses the
Cancel button, or the user chooses the Close command on
the System menu.
Finding Stuff
The next two functions, SHFindFiles and SHFindComputer,
give you access to the two system Find dialogs on the Start
menu. Their ordinal values are 90 and 91 and their function
declarations look like this:
   BOOL WINAPI SHFindFiles(
     LPCITEMIDLIST pidlRoot, 
     LPCITEMIDLIST pidlSavedSearch);
   
   BOOL WINAPI SHFindComputer(
     LPCITEMIDLIST pidlRoot, 
     LPCITEMIDLIST pidlSavedSearch);
      Typically you would specify NULL for both parameters,
which would start the dialogs as if the user had selected
them from the Start menu. However, if you want to search
for files rooted at a particular folder (as if the user had
selected Find from the folder's context menu), you should
set the pidlRoot parameter to the pidl of the folder. This
only works for the SHFindFiles function though - the pa-
rameter is ignored by SHFindComputer. 
      You can also open a previously saved search by speci-
fying the pidl of the file (a .fnd file) in the pidlSavedSearch
parameter. Once again, this parameter is only supported
with the SHFindFiles function - it appears to be ignored by
SHFindComputer.
      For both functions, the dialog is started in a separate
thread so the function call will return almost immediately.
The return value is TRUE if the thread was started suc-
cessfully or FALSE if there was an error of some sort. If
you have specified a value for the pidlRoot parameter, it is
your responsibility to free it when the function returns. The
pidlSavedSearch parameter, on the other hand, is usually
freed by the system - you should only attempt to free it if
the function returns FALSE.
Displaying Object Properties
The last function I'm going to deal with in this section is
SHObjectProperties. This is what you would use to display
the properties dialog for a file or folder. It can also be used
to display the properties for a printer object. The ordinal
value is 178 and the function declaration looks like this:
   BOOL WINAPI SHObjectProperties(
     HWND    hwndOwner, 
     UINT    uFlags, 
     LPCSTR  lpstrName, 
     LPCSTR  lpstrParameters);
      hwndOwner identifies the window that owns the dialog.
lpstrName points to a string containing the path
name or the printer name whose properties
will be displayed. uFlags specifies the type of
name contained in lpstrName (see Figure 5).
lpstrParameters points to a string containing
OPF_PRINTERNAME 0x01
OPF_PATHNAME 0x02
Figure 5  SHObjectProperties Flags
the name of the page that will initially be selected. If lpstr-
Parameters is NULL, the first page on the property sheet
will be selected.
      If the function succeeds, the return value is TRUE. If
the function fails, the return value is FALSE. To get exten-
ded error information, call GetLastError. Note that this
dialog is actually modeless, so when the function returns the
dialog will probably still be open. There is no way of kno-
wing when the user has closed the dialog.
      I should also mention that if you only need to display
the properties for a file or folder, you can quite easily ac-
complish the same thing with a call to the documented
function ShellExecuteEx, specifying "properties" for the
lpVerb parameter. This doesn't appear to work for printer
names though.
Windows NT and Unicode Strings
There is one small catch to all of these functions. Any-
where that you see an LPSTR or LPCSTR type, it should
actually be LPWSTR or LPCWSTR when on Windows NT.
There is no choice of Ansi or Unicode as would be expec-
ted for a documented function. Windows 95 gets the Ansi
version, and Windows NT gets the Unicode version - take
it or leave it.
      If you want your applications to function correctly on
both platforms you are going to have to check what opera-
ting system is in use at runtime. If it is NT, you will need to
convert any string parameters to Unicode before calling the
function. When the function returns, you will also obviously
need to convert any returned strings back to Ansi again. It
may be annoying, but that's the price you pay for using
undocumented functions.
BACK TO HOME
Copyright © 1998-1999 James Holderness. All Rights Reserved
Page last modified: October 1st, 1998

1