mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
857 lines
28 KiB
857 lines
28 KiB
/*
|
|
* ICON.C
|
|
*
|
|
* Implements the OleUIChangeIcon function which invokes the complete
|
|
* Change Icon dialog.
|
|
*
|
|
* Copyright (c)1992 Microsoft Corporation, All Right Reserved
|
|
*/
|
|
|
|
#define STRICT 1
|
|
#include "ole2ui.h"
|
|
#include "common.h"
|
|
#include "utility.h"
|
|
#include "icon.h"
|
|
#include "geticon.h"
|
|
|
|
/*
|
|
* OleUIChangeIcon
|
|
*
|
|
* Purpose:
|
|
* Invokes the standard OLE Change Icon dialog box allowing the user
|
|
* to select an icon from an icon file, executable, or DLL.
|
|
*
|
|
* Parameters:
|
|
* lpCI LPOLEUIChangeIcon pointing to the in-out structure
|
|
* for this dialog.
|
|
*
|
|
* Return Value:
|
|
* UINT OLEUI_SUCCESS or OLEUI_OK if all is well, otherwise
|
|
* an error value.
|
|
*/
|
|
|
|
STDAPI_(UINT) OleUIChangeIcon(LPOLEUICHANGEICON lpCI)
|
|
{
|
|
UINT uRet;
|
|
HGLOBAL hMemDlg=NULL;
|
|
|
|
uRet=UStandardValidation((LPOLEUISTANDARD)lpCI, sizeof(OLEUICHANGEICON)
|
|
, &hMemDlg);
|
|
|
|
if (OLEUI_SUCCESS!=uRet)
|
|
return uRet;
|
|
|
|
#if defined( OBSOLETE )
|
|
if (NULL==lpCI->hMetaPict)
|
|
uRet=OLEUI_CIERR_MUSTHAVECURRENTMETAFILE;
|
|
#endif
|
|
|
|
if (lpCI->dwFlags & CIF_USEICONEXE)
|
|
{
|
|
if ( (NULL == lpCI->szIconExe)
|
|
|| (IsBadReadPtr(lpCI->szIconExe, lpCI->cchIconExe))
|
|
|| (IsBadWritePtr(lpCI->szIconExe, lpCI->cchIconExe)) )
|
|
uRet = OLEUI_CIERR_SZICONEXEINVALID;
|
|
|
|
}
|
|
|
|
// REVIEW: how do we validate the CLSID?
|
|
/*
|
|
if ('\0'==*((LPSTR)&lpCI->clsid))
|
|
uRet=OLEUI_CIERR_MUSTHAVECLSID;
|
|
*/
|
|
if (OLEUI_ERR_STANDARDMIN <= uRet)
|
|
{
|
|
if (NULL!=hMemDlg)
|
|
FreeResource(hMemDlg);
|
|
|
|
return uRet;
|
|
}
|
|
|
|
//Now that we've validated everything, we can invoke the dialog.
|
|
return UStandardInvocation(ChangeIconDialogProc, (LPOLEUISTANDARD)lpCI
|
|
, hMemDlg, MAKEINTRESOURCE(IDD_CHANGEICON));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* ChangeIconDialogProc
|
|
*
|
|
* Purpose:
|
|
* Implements the OLE Change Icon dialog as invoked through the
|
|
* OleUIChangeIcon function.
|
|
*
|
|
* Parameters:
|
|
* Standard
|
|
*
|
|
* Return Value:
|
|
* Standard
|
|
*/
|
|
|
|
BOOL CALLBACK EXPORT ChangeIconDialogProc(HWND hDlg, UINT iMsg
|
|
, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LPCHANGEICON lpCI;
|
|
HICON hIcon;
|
|
HGLOBAL hMetaPict;
|
|
BOOL fOK=FALSE;
|
|
UINT uRet=0;
|
|
LPTSTR psz;
|
|
TCHAR szTemp[OLEUI_CCHPATHMAX];
|
|
|
|
//Declare Win16/Win32 compatible WM_COMMAND parameters.
|
|
COMMANDPARAMS(wID, wCode, hWndMsg);
|
|
|
|
lpCI=(LPCHANGEICON)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
|
|
|
|
//If the hook processed the message, we're done.
|
|
if (0!=uRet)
|
|
return uRet;
|
|
|
|
//Process the temination message
|
|
if (iMsg==uMsgEndDialog)
|
|
{
|
|
//Insure that icons are properly destroyed.
|
|
SendDlgItemMessage(hDlg, ID_ICONLIST, LB_RESETCONTENT, 0, 0L);
|
|
|
|
StandardCleanup(lpCI, hDlg);
|
|
EndDialog(hDlg, wParam);
|
|
return TRUE;
|
|
}
|
|
|
|
switch (iMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
FChangeIconInit(hDlg, wParam, lParam);
|
|
return TRUE;
|
|
|
|
|
|
case WM_MEASUREITEM:
|
|
{
|
|
LPMEASUREITEMSTRUCT lpMI=(LPMEASUREITEMSTRUCT)lParam;
|
|
|
|
//All icons are system metric+padding in width and height
|
|
lpMI->itemWidth =GetSystemMetrics(SM_CXICON)+CXICONPAD;
|
|
lpMI->itemHeight=GetSystemMetrics(SM_CYICON)+CYICONPAD;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_DRAWITEM:
|
|
return FDrawListIcon((LPDRAWITEMSTRUCT)lParam);
|
|
|
|
|
|
case WM_DELETEITEM:
|
|
//Free the GDI object for the item
|
|
DestroyIcon((HICON)LOWORD(((LPDELETEITEMSTRUCT)lParam)->itemData));
|
|
break;
|
|
|
|
|
|
case WM_COMMAND:
|
|
switch (wID)
|
|
{
|
|
case ID_CURRENT:
|
|
case ID_DEFAULT:
|
|
case ID_FROMFILE:
|
|
UpdateResultIcon(lpCI, hDlg, wID);
|
|
break;
|
|
|
|
case ID_LABELEDIT:
|
|
//When the edit loses focus, update the result display
|
|
if (EN_KILLFOCUS==wCode)
|
|
{
|
|
GetDlgItemText(hDlg, ID_LABELEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR));
|
|
SetDlgItemText(hDlg, ID_RESULTLABEL, szTemp);
|
|
}
|
|
break;
|
|
|
|
case ID_FROMFILEEDIT:
|
|
//If the text changed, remove any selection in the list.
|
|
GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR));
|
|
|
|
if (lpCI && lstrcmpi(szTemp, lpCI->szFile))
|
|
{
|
|
SendDlgItemMessage(hDlg, ID_ICONLIST, LB_SETCURSEL
|
|
, (WPARAM)-1, 0);
|
|
|
|
//Also force selection of ID_FROMFILE
|
|
CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_FROMFILE);
|
|
}
|
|
break;
|
|
|
|
|
|
case ID_ICONLIST:
|
|
switch (wCode)
|
|
{
|
|
case LBN_SETFOCUS:
|
|
//If we got the focus, see about updating.
|
|
GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp
|
|
, sizeof(szTemp)/sizeof(TCHAR));
|
|
|
|
//Check if file changed and update the list if so
|
|
if (lpCI && 0!=lstrcmpi(szTemp, lpCI->szFile))
|
|
{
|
|
lstrcpy(lpCI->szFile, szTemp);
|
|
UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile);
|
|
UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
|
|
}
|
|
break;
|
|
|
|
case LBN_SELCHANGE:
|
|
UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
|
|
break;
|
|
|
|
case LBN_DBLCLK:
|
|
//Same as pressing OK.
|
|
SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case ID_BROWSE:
|
|
{
|
|
DWORD dwOfnFlags;
|
|
|
|
/*
|
|
* To allow the hook to customize the browse dialog, we
|
|
* send OLEUI_MSG_BROWSE. If the hook returns FALSE
|
|
* we use the default, otherwise we trust that it retrieved
|
|
* a filename for us. This mechanism prevents hooks from
|
|
* trapping ID_BROWSE to customize the dialog and from
|
|
* trying to figure out what we do after we have the name.
|
|
*/
|
|
|
|
//Copy for reference
|
|
LSTRCPYN(szTemp, lpCI->szFile, sizeof(szTemp)/sizeof(TCHAR));
|
|
|
|
uRet=UStandardHook(lpCI, hDlg, uMsgBrowse, OLEUI_CCHPATHMAX_SIZE
|
|
, (LONG)(LPSTR)lpCI->szFile);
|
|
|
|
dwOfnFlags = OFN_FILEMUSTEXIST;
|
|
if (lpCI->lpOCI->dwFlags & CIF_SHOWHELP)
|
|
dwOfnFlags |= OFN_SHOWHELP;
|
|
|
|
if (0==uRet)
|
|
uRet=(BOOL)Browse(hDlg, lpCI->szFile, NULL, OLEUI_CCHPATHMAX_SIZE, IDS_ICONFILTERS, dwOfnFlags);
|
|
|
|
/*
|
|
* Only reinitialize if the file changed, so if we got
|
|
* TRUE from the hook but the user hit Cancel, we don't
|
|
* spend time unecessarily refilling the list.
|
|
*/
|
|
if (0!=uRet && 0!=lstrcmpi(szTemp, lpCI->szFile))
|
|
{
|
|
CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_FROMFILE);
|
|
SetDlgItemText(hDlg, ID_FROMFILEEDIT, lpCI->szFile);
|
|
UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile);
|
|
UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case IDOK:
|
|
/*
|
|
* If the user pressed enter, compare the current file
|
|
* and the one we have stored. If they match, then
|
|
* refill the listbox instead of closing down. This is
|
|
* so the user can press Enter in the edit control as
|
|
* they would expect to be able to do.
|
|
*/
|
|
GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR));
|
|
|
|
//Check if the file changed at all.
|
|
if (0!=lstrcmpi(szTemp, lpCI->szFile))
|
|
{
|
|
lstrcpy(lpCI->szFile, szTemp);
|
|
UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile);
|
|
UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
|
|
|
|
//Eat this message to prevent focus change.
|
|
return TRUE;
|
|
}
|
|
|
|
// Check if the file name is valid
|
|
// (if FromFile is enabled)
|
|
if (ID_FROMFILE & lpCI->dwFlags)
|
|
{
|
|
OFSTRUCT of;
|
|
HWND hWnd;
|
|
if (HFILE_ERROR==DoesFileExist(lpCI->szFile, &of))
|
|
{
|
|
OpenFileError(hDlg, of.nErrCode, lpCI->szFile);
|
|
hWnd = GetDlgItem(hDlg, ID_FROMFILEEDIT);
|
|
SetFocus(hWnd);
|
|
SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1));
|
|
return TRUE; // eat this message
|
|
}
|
|
}
|
|
|
|
if ((HWND)LOWORD(lParam) != GetFocus())
|
|
SetFocus((HWND)LOWORD(lParam));
|
|
|
|
/*
|
|
* On closing, create a new metafilepict with the
|
|
* current icon and label, destroying the old structure.
|
|
*
|
|
* Since we make a copy of the icon by placing it into
|
|
* the metafile, we have to make sure we delete the
|
|
* icon in the current field. When the listbox is
|
|
* destroyed WM_DELETEITEMs will clean it up appropriately.
|
|
*/
|
|
|
|
hIcon=(HICON)SendDlgItemMessage(hDlg, ID_RESULTICON
|
|
, STM_GETICON, 0, 0L);
|
|
|
|
/*
|
|
* If default is selected then we get the source
|
|
* information from registrion database for the
|
|
* current class to put in the metafile. If current
|
|
* is selected the we just retrieve the original file
|
|
* again and recreate the metafile. If from file is
|
|
* selected we use the current filename from the
|
|
* control and the current listbox selection.
|
|
*/
|
|
|
|
psz=lpCI->szFile;
|
|
|
|
if (lpCI->dwFlags & CIF_SELECTDEFAULT)
|
|
{
|
|
psz=lpCI->szDefIconFile;
|
|
lpCI->iIcon=lpCI->iDefIcon;
|
|
hIcon=lpCI->hDefIcon;
|
|
}
|
|
|
|
if (lpCI->dwFlags & CIF_SELECTCURRENT)
|
|
{
|
|
//Go get the current icon source back.
|
|
OleUIMetafilePictExtractIconSource(lpCI->lpOCI->hMetaPict
|
|
, psz, &lpCI->iIcon);
|
|
}
|
|
|
|
if (lpCI->dwFlags & CIF_SELECTFROMFILE)
|
|
{
|
|
GetDlgItemText(hDlg, ID_FROMFILEEDIT, psz, OLEUI_CCHPATHMAX);
|
|
|
|
lpCI->iIcon=(UINT)SendDlgItemMessage(hDlg
|
|
, ID_ICONLIST, LB_GETCURSEL, 0, 0L);
|
|
}
|
|
|
|
|
|
//Get the label and go create the metafile
|
|
GetDlgItemText(hDlg, ID_LABELEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR));
|
|
|
|
//If psz is NULL (default) we get no source comments.
|
|
|
|
#ifdef OLE201
|
|
hMetaPict=OleUIMetafilePictFromIconAndLabel(hIcon,
|
|
szTemp, psz, lpCI->iIcon);
|
|
#endif
|
|
|
|
//Clean up the current icon that we extracted.
|
|
hIcon=(HICON)SendDlgItemMessage(hDlg, ID_CURRENTICON
|
|
, STM_GETICON, 0, 0L);
|
|
DestroyIcon(hIcon);
|
|
|
|
//Clean up the default icon
|
|
DestroyIcon(lpCI->hDefIcon);
|
|
|
|
// Remove the prop set on our parent
|
|
RemoveProp(lpCI->lpOCI->hWndOwner, PROP_HWND_CHGICONDLG);
|
|
|
|
if (NULL==hMetaPict)
|
|
SendMessage(hDlg, uMsgEndDialog, OLEUI_FALSE, 0L);
|
|
|
|
OleUIMetafilePictIconFree(lpCI->lpOCI->hMetaPict);
|
|
lpCI->lpOCI->hMetaPict=hMetaPict;
|
|
|
|
lpCI->lpOCI->dwFlags = lpCI->dwFlags;
|
|
|
|
SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
|
|
break;
|
|
|
|
|
|
case IDCANCEL:
|
|
//Clean up the current icon that we extracted.
|
|
hIcon=(HICON)SendDlgItemMessage(hDlg, ID_CURRENTICON
|
|
, STM_GETICON, 0, 0L);
|
|
DestroyIcon(hIcon);
|
|
|
|
//Clean up the default icon
|
|
DestroyIcon(lpCI->hDefIcon);
|
|
|
|
// Remove the prop set on our parent
|
|
RemoveProp(lpCI->lpOCI->hWndOwner, PROP_HWND_CHGICONDLG);
|
|
|
|
//We leave hMetaPict intact on Cancel; caller's responsibility
|
|
SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
|
|
break;
|
|
|
|
|
|
case ID_OLEUIHELP:
|
|
PostMessage(lpCI->lpOCI->hWndOwner, uMsgHelp,
|
|
(WPARAM)hDlg, MAKELPARAM(IDD_CHANGEICON, 0));
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
if (lpCI && iMsg == lpCI->nBrowseHelpID) {
|
|
PostMessage(lpCI->lpOCI->hWndOwner, uMsgHelp,
|
|
(WPARAM)hDlg, MAKELPARAM(IDD_CHANGEICONBROWSE, 0));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* FChangeIconInit
|
|
*
|
|
* Purpose:
|
|
* WM_INITIDIALOG handler for the Change Icon dialog box.
|
|
*
|
|
* Parameters:
|
|
* hDlg HWND of the dialog
|
|
* wParam WPARAM of the message
|
|
* lParam LPARAM of the message
|
|
*
|
|
* Return Value:
|
|
* BOOL Value to return for WM_INITDIALOG.
|
|
*/
|
|
|
|
BOOL FChangeIconInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LPCHANGEICON lpCI;
|
|
LPOLEUICHANGEICON lpOCI;
|
|
HFONT hFont;
|
|
HWND hList;
|
|
UINT cyList;
|
|
RECT rc, rcG;
|
|
UINT uID;
|
|
|
|
//1. Copy the structure at lParam into our instance memory.
|
|
lpCI=(LPCHANGEICON)LpvStandardInit(hDlg, sizeof(CHANGEICON), TRUE, &hFont);
|
|
|
|
//PvStandardInit send a termination to us already.
|
|
if (NULL==lpCI)
|
|
return FALSE;
|
|
|
|
//Save the original pointer and copy necessary information.
|
|
lpOCI=(LPOLEUICHANGEICON)lParam;
|
|
|
|
lpCI->lpOCI =lpOCI;
|
|
lpCI->dwFlags=lpOCI->dwFlags;
|
|
|
|
//Go extract the icon source from the metafile.
|
|
OleUIMetafilePictExtractIconSource(lpOCI->hMetaPict, lpCI->szFile, &lpCI->iIcon);
|
|
|
|
//Go extract the icon and the label from the metafile
|
|
OleUIMetafilePictExtractLabel(lpOCI->hMetaPict, lpCI->szLabel, OLEUI_CCHLABELMAX_SIZE, NULL);
|
|
lpCI->hCurIcon=OleUIMetafilePictExtractIcon(lpOCI->hMetaPict);
|
|
|
|
//2. If we got a font, send it to the necessary controls.
|
|
if (NULL!=hFont)
|
|
{
|
|
SendDlgItemMessage(hDlg, ID_RESULTLABEL, WM_SETFONT
|
|
, (WPARAM)hFont, 0L);
|
|
}
|
|
|
|
|
|
//3. Show or hide the help button
|
|
if (!(lpCI->dwFlags & CIF_SHOWHELP))
|
|
StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE);
|
|
|
|
|
|
/*
|
|
* 4. Set text limits and initial control values. If we're given
|
|
* an intial label we set it in the edit and static controls.
|
|
* If we don't, then we copy the default contents of the static
|
|
* control into the edit control, meaning that only the default
|
|
* static control string need be localized.
|
|
*/
|
|
|
|
SendDlgItemMessage(hDlg, ID_LABELEDIT, EM_LIMITTEXT, OLEUI_CCHLABELMAX, 0L);
|
|
SendDlgItemMessage(hDlg, ID_FROMFILEEDIT, EM_LIMITTEXT, OLEUI_CCHPATHMAX, 0L);
|
|
SetDlgItemText(hDlg, ID_FROMFILEEDIT, lpCI->szFile);
|
|
|
|
//Copy the label text into the edit and static controls.
|
|
SetDlgItemText(hDlg, ID_LABELEDIT, lpCI->szLabel);
|
|
SetDlgItemText(hDlg, ID_RESULTLABEL, lpCI->szLabel);
|
|
|
|
|
|
lpCI->hDefIcon = NULL;
|
|
|
|
if (lpCI->dwFlags & CIF_USEICONEXE)
|
|
{
|
|
lpCI->hDefIcon = ExtractIcon(ghInst, lpCI->lpOCI->szIconExe, 0);
|
|
|
|
if (NULL != lpCI->hDefIcon)
|
|
{
|
|
lstrcpy(lpCI->szDefIconFile, lpCI->lpOCI->szIconExe);
|
|
lpCI->iDefIcon = 0;
|
|
}
|
|
}
|
|
|
|
|
|
if (NULL == lpCI->hDefIcon)
|
|
{
|
|
HGLOBAL hMetaPict;
|
|
|
|
#ifdef OLE201
|
|
hMetaPict = GetIconOfClass(ghInst,
|
|
&lpCI->lpOCI->clsid,
|
|
NULL,
|
|
TRUE);
|
|
#endif
|
|
|
|
lpCI->hDefIcon = OleUIMetafilePictExtractIcon(hMetaPict);
|
|
|
|
OleUIMetafilePictExtractIconSource(hMetaPict,
|
|
lpCI->szDefIconFile,
|
|
&lpCI->iDefIcon);
|
|
|
|
OleUIMetafilePictIconFree(hMetaPict);
|
|
}
|
|
|
|
|
|
//Initialize all the icon displays.
|
|
SendDlgItemMessage(hDlg, ID_CURRENTICON, STM_SETICON
|
|
, (WPARAM)lpCI->hCurIcon, 0L);
|
|
SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_SETICON
|
|
, (WPARAM)lpCI->hDefIcon, 0L);
|
|
SendDlgItemMessage(hDlg, ID_RESULTICON, STM_SETICON
|
|
, (WPARAM)lpCI->hCurIcon, 0L);
|
|
|
|
|
|
/*
|
|
* 5. Since we cannot predict the size of icons on any display,
|
|
* we have to resize the icon listbox to the size of an icon
|
|
* (plus padding), a scrollbar, and two borders (top & bottom).
|
|
*/
|
|
cyList=GetSystemMetrics(SM_CYICON)+GetSystemMetrics(SM_CYHSCROLL)
|
|
+GetSystemMetrics(SM_CYBORDER)*2+CYICONPAD;
|
|
|
|
hList=GetDlgItem(hDlg, ID_ICONLIST);
|
|
GetClientRect(hList, &rc);
|
|
SetWindowPos(hList, NULL, 0, 0, rc.right, cyList
|
|
, SWP_NOMOVE | SWP_NOZORDER);
|
|
|
|
//Set the columns in this multi-column listbox to hold one icon
|
|
SendMessage(hList, LB_SETCOLUMNWIDTH
|
|
, GetSystemMetrics(SM_CXICON)+CXICONPAD,0L);
|
|
|
|
/*
|
|
* 5a. If the listbox expanded below the group box, then size
|
|
* the groupbox down, move the label static and exit controls
|
|
* down, and expand the entire dialog appropriately.
|
|
*/
|
|
|
|
GetWindowRect(hList, &rc);
|
|
GetWindowRect(GetDlgItem(hDlg, ID_GROUP), &rcG);
|
|
|
|
if (rc.bottom > rcG.bottom)
|
|
{
|
|
//Calculate amount to move things down.
|
|
cyList=(rcG.bottom-rcG.top)-(rc.bottom-rc.top-cyList);
|
|
|
|
//Expand the group box.
|
|
rcG.right -=rcG.left;
|
|
rcG.bottom-=rcG.top;
|
|
SetWindowPos(GetDlgItem(hDlg, ID_GROUP), NULL, 0, 0
|
|
, rcG.right, rcG.bottom+cyList
|
|
, SWP_NOMOVE | SWP_NOZORDER);
|
|
|
|
//Expand the dialog box.
|
|
GetClientRect(hDlg, &rc);
|
|
SetWindowPos(hDlg, NULL, 0, 0, rc.right, rc.bottom+cyList
|
|
, SWP_NOMOVE | SWP_NOZORDER);
|
|
|
|
//Move the label and edit controls down.
|
|
GetClientRect(GetDlgItem(hDlg, ID_LABEL), &rc);
|
|
SetWindowPos(GetDlgItem(hDlg, ID_LABEL), NULL, 0, cyList
|
|
, rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER);
|
|
|
|
GetClientRect(GetDlgItem(hDlg, ID_LABELEDIT), &rc);
|
|
SetWindowPos(GetDlgItem(hDlg, ID_LABELEDIT), NULL, 0, cyList
|
|
, rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
|
|
|
|
/*
|
|
* 6. Select Current, Default, or From File radiobuttons appropriately.
|
|
* The CheckRadioButton call sends WM_COMMANDs which handle
|
|
* other actions. Note that if we check From File, which
|
|
* takes an icon from the list, we better fill the list.
|
|
* This will also fill the list even if default is selected.
|
|
*/
|
|
|
|
if (0!=UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile))
|
|
{
|
|
//If szFile worked, then select the source icon in the listbox.
|
|
SendDlgItemMessage(hDlg, ID_ICONLIST, LB_SETCURSEL, lpCI->iIcon, 0L);
|
|
}
|
|
|
|
|
|
if (lpCI->dwFlags & CIF_SELECTCURRENT)
|
|
CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_CURRENT);
|
|
else
|
|
{
|
|
uID=(lpCI->dwFlags & CIF_SELECTFROMFILE) ? ID_FROMFILE : ID_DEFAULT;
|
|
CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, uID);
|
|
}
|
|
|
|
//7. Give our parent window access to our hDlg (via a special SetProp).
|
|
// The PasteSpecial dialog may need to force our dialog down if the
|
|
// clipboard contents change underneath it. if so it will send
|
|
// us a IDCANCEL command.
|
|
SetProp(lpCI->lpOCI->hWndOwner, PROP_HWND_CHGICONDLG, hDlg);
|
|
|
|
lpCI->nBrowseHelpID = RegisterWindowMessage(HELPMSGSTRING);
|
|
|
|
//8. Call the hook with lCustData in lParam
|
|
UStandardHook(lpCI, hDlg, WM_INITDIALOG, wParam, lpOCI->lCustData);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* UFillIconList
|
|
*
|
|
* Purpose:
|
|
* Given a listbox and a filename, attempts to open that file and
|
|
* read all the icons that exist therein, adding them to the listbox
|
|
* hList as owner-draw items. If the file does not exist or has no
|
|
* icons, then you get no icons and an appropriate warning message.
|
|
*
|
|
* Parameters:
|
|
* hDlg HWND of the dialog containing the listbox.
|
|
* idList UINT identifier of the listbox to fill.
|
|
* pszFile LPSTR of the file from which to extract icons.
|
|
*
|
|
* Return Value:
|
|
* UINT Number of items added to the listbox. 0 on failure.
|
|
*/
|
|
|
|
UINT UFillIconList(HWND hDlg, UINT idList, LPTSTR pszFile)
|
|
{
|
|
HWND hList;
|
|
UINT i;
|
|
UINT cIcons=0;
|
|
HCURSOR hCur;
|
|
HICON hIcon;
|
|
OFSTRUCT of;
|
|
|
|
if (NULL==hDlg || !IsWindow(hDlg) || NULL==pszFile)
|
|
return 0;
|
|
|
|
hList=GetDlgItem(hDlg, idList);
|
|
|
|
if (NULL==hList)
|
|
return 0;
|
|
|
|
//Clean out the listbox.
|
|
SendMessage(hList, LB_RESETCONTENT, 0, 0L);
|
|
|
|
//If we have an empty string, just exit leaving the listbox empty as well
|
|
if (0==lstrlen(pszFile))
|
|
return 0;
|
|
|
|
//Turn on the hourglass
|
|
hCur=HourGlassOn();
|
|
|
|
//Check if the file is valid.
|
|
if (HFILE_ERROR!=DoesFileExist(pszFile, &of))
|
|
{
|
|
#ifdef EXTRACTICONWORKS
|
|
//Get the icon count for this file.
|
|
cIcons=(UINT)ExtractIcon(ghInst, pszFile, (UINT)-1);
|
|
#else
|
|
/*
|
|
* ExtractIcon in Windows 3.1 with -1 eats a selector, leaving an
|
|
* extra global memory object around for this applciation. Since
|
|
* changing icons may happen very often with all OLE apps in
|
|
* the system, we have to work around it. So we'll say we
|
|
* have lots of icons and just call ExtractIcon until it
|
|
* fails. We check if there's any around by trying to get
|
|
* the first one.
|
|
*/
|
|
cIcons=0xFFFF;
|
|
|
|
hIcon=ExtractIcon(ghInst, pszFile, 0);
|
|
|
|
//Fake a failure with cIcons=0, or cleanup hIcon from this test.
|
|
if (32 > (UINT)hIcon)
|
|
cIcons=0;
|
|
else
|
|
DestroyIcon(hIcon);
|
|
#endif
|
|
|
|
if (0!=cIcons)
|
|
{
|
|
SendMessage(hList, WM_SETREDRAW, FALSE, 0L);
|
|
|
|
for (i=0; i<cIcons; i++)
|
|
{
|
|
hIcon=ExtractIcon(ghInst, pszFile, i);
|
|
|
|
if (32 < (UINT)hIcon)
|
|
SendMessage(hList, LB_ADDSTRING, 0, (LONG)(UINT)hIcon);
|
|
#ifndef EXTRACTICONWORKS
|
|
else
|
|
{
|
|
//ExtractIcon failed, so let's leave now.
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//Force complete repaint
|
|
SendMessage(hList, WM_SETREDRAW, TRUE, 0L);
|
|
InvalidateRect(hList, NULL, TRUE);
|
|
|
|
//Select an icon
|
|
SendMessage(hList, LB_SETCURSEL, 0, 0L);
|
|
}
|
|
else
|
|
ErrorWithFile(hDlg, ghInst, IDS_CINOICONSINFILE, pszFile, MB_OK);
|
|
}
|
|
else
|
|
OpenFileError(hDlg, of.nErrCode, pszFile);
|
|
|
|
HourGlassOff(hCur);
|
|
return cIcons;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* FDrawListIcon
|
|
*
|
|
* Purpose:
|
|
* Handles WM_DRAWITEM for the icon listbox.
|
|
*
|
|
* Parameters:
|
|
* lpDI LPDRAWITEMSTRUCT from WM_DRAWITEM
|
|
*
|
|
* Return Value:
|
|
* BOOL TRUE if we did anything, FALSE if there are no items
|
|
* in the list.
|
|
*/
|
|
|
|
BOOL FDrawListIcon(LPDRAWITEMSTRUCT lpDI)
|
|
{
|
|
COLORREF cr;
|
|
|
|
/*
|
|
* If there are no items in the list, then itemID is negative according
|
|
* to the Win3.1 SDK. Unfortunately DRAWITEMSTRUCT has an unsigned int
|
|
* for this field, so we need the typecast to do a signed comparison.
|
|
*/
|
|
if ((int)lpDI->itemID < 0)
|
|
return FALSE;
|
|
|
|
/*
|
|
* For selection or draw entire case we just draw the entire item all
|
|
* over again. For focus cases, we only call DrawFocusRect.
|
|
*/
|
|
|
|
if (lpDI->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))
|
|
{
|
|
//Clear background and draw the icon.
|
|
if (lpDI->itemState & ODS_SELECTED)
|
|
cr=SetBkColor(lpDI->hDC, GetSysColor(COLOR_HIGHLIGHT));
|
|
else
|
|
cr=SetBkColor(lpDI->hDC, GetSysColor(COLOR_WINDOW));
|
|
|
|
//Draw a cheap rectangle.
|
|
ExtTextOut(lpDI->hDC, 0, 0, ETO_OPAQUE, &lpDI->rcItem
|
|
, NULL, 0, NULL);
|
|
|
|
DrawIcon(lpDI->hDC, lpDI->rcItem.left+(CXICONPAD/2)
|
|
, lpDI->rcItem.top+(CYICONPAD/2)
|
|
, (HICON)LOWORD(lpDI->itemData));
|
|
|
|
//Restore original background for DrawFocusRect
|
|
SetBkColor(lpDI->hDC, cr);
|
|
}
|
|
|
|
//Always change focus on the focus action.
|
|
if (lpDI->itemAction & ODA_FOCUS || lpDI->itemState & ODS_FOCUS)
|
|
DrawFocusRect(lpDI->hDC, &lpDI->rcItem);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* UpdateResultIcon
|
|
*
|
|
* Purpose:
|
|
* Updates the result icon using the current icon in the default display
|
|
* or the icon listbox depending on fFromDefault.
|
|
*
|
|
* Parameters:
|
|
* lpCI LPCHANGEICON containing dialog flags.
|
|
* hDlg HWND of the dialog
|
|
* uID UINT identifying the radiobutton selected.
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*/
|
|
|
|
void UpdateResultIcon(LPCHANGEICON lpCI, HWND hDlg, UINT uID)
|
|
{
|
|
UINT iSel;
|
|
LONG lTemp=LB_ERR;
|
|
|
|
lpCI->dwFlags &= ~(CIF_SELECTCURRENT | CIF_SELECTDEFAULT | CIF_SELECTFROMFILE);
|
|
|
|
switch (uID)
|
|
{
|
|
case ID_CURRENT:
|
|
lTemp=SendDlgItemMessage(hDlg, ID_CURRENTICON, STM_GETICON, 0, 0L);
|
|
lpCI->dwFlags |= CIF_SELECTCURRENT;
|
|
break;
|
|
|
|
case ID_DEFAULT:
|
|
lTemp=SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_GETICON, 0, 0L);
|
|
lpCI->dwFlags |= CIF_SELECTDEFAULT;
|
|
break;
|
|
|
|
case ID_FROMFILE:
|
|
//Get the selected icon from the list and place it in the result
|
|
lpCI->dwFlags |= CIF_SELECTFROMFILE;
|
|
|
|
iSel=(UINT)SendDlgItemMessage(hDlg, ID_ICONLIST, LB_GETCURSEL, 0, 0L);
|
|
if ((UINT)LB_ERR==iSel)
|
|
lTemp=SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_GETICON, 0, 0L);
|
|
else
|
|
SendDlgItemMessage(hDlg, ID_ICONLIST, LB_GETTEXT, iSel
|
|
, (LPARAM)(LPLONG)&lTemp);
|
|
|
|
break;
|
|
}
|
|
|
|
if ((LONG)LB_ERR!=lTemp)
|
|
SendDlgItemMessage(hDlg, ID_RESULTICON, STM_SETICON, LOWORD(lTemp), 0L);
|
|
return;
|
|
}
|
|
|
|
|