|
|
1.1 root 1: /*
2: * ICON.C
3: *
4: * Implements the OleUIChangeIcon function which invokes the complete
5: * Change Icon dialog.
6: *
7: * Copyright (c)1992 Microsoft Corporation, All Right Reserved
8: */
9:
10: #define STRICT 1
11: #include "ole2ui.h"
12: #include "common.h"
13: #include "utility.h"
14: #include "icon.h"
15: #include "geticon.h"
16:
17: /*
18: * OleUIChangeIcon
19: *
20: * Purpose:
21: * Invokes the standard OLE Change Icon dialog box allowing the user
22: * to select an icon from an icon file, executable, or DLL.
23: *
24: * Parameters:
25: * lpCI LPOLEUIChangeIcon pointing to the in-out structure
26: * for this dialog.
27: *
28: * Return Value:
29: * UINT OLEUI_SUCCESS or OLEUI_OK if all is well, otherwise
30: * an error value.
31: */
32:
33: STDAPI_(UINT) OleUIChangeIcon(LPOLEUICHANGEICON lpCI)
34: {
35: UINT uRet;
36: HGLOBAL hMemDlg=NULL;
37:
38: uRet=UStandardValidation((LPOLEUISTANDARD)lpCI, sizeof(OLEUICHANGEICON)
39: , &hMemDlg);
40:
41: if (OLEUI_SUCCESS!=uRet)
42: return uRet;
43:
44: if (NULL==lpCI->hMetaPict)
45: uRet=OLEUI_CIERR_MUSTHAVECURRENTMETAFILE;
46:
47: if (lpCI->dwFlags & CIF_USEICONEXE)
48: {
49: if ( (NULL == lpCI->szIconExe)
50: || (IsBadReadPtr(lpCI->szIconExe, lpCI->cchIconExe))
51: || (IsBadWritePtr(lpCI->szIconExe, lpCI->cchIconExe)) )
52: uRet = OLEUI_CIERR_SZICONEXEINVALID;
53:
54: }
55:
56: // REVIEW: how do we validate the CLSID?
57: /*
58: if ('\0'==*((LPSTR)&lpCI->clsid))
59: uRet=OLEUI_CIERR_MUSTHAVECLSID;
60: */
61: if (OLEUI_ERR_STANDARDMIN <= uRet)
62: {
63: if (NULL!=hMemDlg)
64: FreeResource(hMemDlg);
65:
66: return uRet;
67: }
68:
69: //Now that we've validated everything, we can invoke the dialog.
70: return UStandardInvocation(ChangeIconDialogProc, (LPOLEUISTANDARD)lpCI
71: , hMemDlg, MAKEINTRESOURCE(IDD_CHANGEICON));
72: }
73:
74:
75:
76:
77:
78: /*
79: * ChangeIconDialogProc
80: *
81: * Purpose:
82: * Implements the OLE Change Icon dialog as invoked through the
83: * OleUIChangeIcon function.
84: *
85: * Parameters:
86: * Standard
87: *
88: * Return Value:
89: * Standard
90: */
91:
92: BOOL CALLBACK EXPORT ChangeIconDialogProc(HWND hDlg, UINT iMsg
93: , WPARAM wParam, LPARAM lParam)
94: {
95: LPCHANGEICON lpCI;
96: HICON hIcon;
97: HGLOBAL hMetaPict;
98: BOOL fOK=FALSE;
99: UINT uRet=0;
100: LPSTR psz;
101: char szTemp[OLEUI_CCHPATHMAX];
102:
103: //Declare Win16/Win32 compatible WM_COMMAND parameters.
104: COMMANDPARAMS(wID, wCode, hWndMsg);
105:
106: lpCI=(LPCHANGEICON)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
107:
108: //If the hook processed the message, we're done.
109: if (0!=uRet)
110: return uRet;
111:
112: //Process the temination message
113: if (iMsg==uMsgEndDialog)
114: {
115: //Insure that icons are properly destroyed.
116: SendDlgItemMessage(hDlg, ID_ICONLIST, LB_RESETCONTENT, 0, 0L);
117:
118: StandardCleanup(lpCI, hDlg);
119: EndDialog(hDlg, wParam);
120: return TRUE;
121: }
122:
123: switch (iMsg)
124: {
125: case WM_INITDIALOG:
126: FChangeIconInit(hDlg, wParam, lParam);
127: return TRUE;
128:
129:
130: case WM_MEASUREITEM:
131: {
132: LPMEASUREITEMSTRUCT lpMI=(LPMEASUREITEMSTRUCT)lParam;
133:
134: //All icons are system metric+padding in width and height
135: lpMI->itemWidth =GetSystemMetrics(SM_CXICON)+CXICONPAD;
136: lpMI->itemHeight=GetSystemMetrics(SM_CYICON)+CYICONPAD;
137: }
138: break;
139:
140:
141: case WM_DRAWITEM:
142: return FDrawListIcon((LPDRAWITEMSTRUCT)lParam);
143:
144:
145: case WM_DELETEITEM:
146: //Free the GDI object for the item
147: DestroyIcon((HICON)LOWORD(((LPDELETEITEMSTRUCT)lParam)->itemData));
148: break;
149:
150:
151: case WM_COMMAND:
152: switch (wID)
153: {
154: case ID_CURRENT:
155: case ID_DEFAULT:
156: case ID_FROMFILE:
157: UpdateResultIcon(lpCI, hDlg, wID);
158: break;
159:
160: case ID_LABELEDIT:
161: //When the edit loses focus, update the result display
162: if (EN_KILLFOCUS==wCode)
163: {
164: GetDlgItemText(hDlg, ID_LABELEDIT, szTemp, sizeof(szTemp));
165: SetDlgItemText(hDlg, ID_RESULTLABEL, szTemp);
166: }
167: break;
168:
169: case ID_FROMFILEEDIT:
170: //If the text changed, remove any selection in the list.
171: GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp, sizeof(szTemp));
172:
173: if (lstrcmpi(szTemp, lpCI->szFile))
174: {
175: SendDlgItemMessage(hDlg, ID_ICONLIST, LB_SETCURSEL
176: , (WPARAM)-1, 0);
177:
178: //Also force selection of ID_FROMFILE
179: CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_FROMFILE);
180: }
181: break;
182:
183:
184: case ID_ICONLIST:
185: switch (wCode)
186: {
187: case LBN_SETFOCUS:
188: //If we got the focus, see about updating.
189: GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp
190: , sizeof(szTemp));
191:
192: //Check if file changed and update the list if so
193: if (0!=lstrcmpi(szTemp, lpCI->szFile))
194: {
195: lstrcpy(lpCI->szFile, szTemp);
196: UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile);
197: UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
198: }
199: break;
200:
201: case LBN_SELCHANGE:
202: UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
203: break;
204:
205: case LBN_DBLCLK:
206: //Same as pressing OK.
207: SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
208: break;
209: }
210: break;
211:
212:
213: case ID_BROWSE:
214: {
215: DWORD dwOfnFlags;
216:
217: /*
218: * To allow the hook to customize the browse dialog, we
219: * send OLEUI_MSG_BROWSE. If the hook returns FALSE
220: * we use the default, otherwise we trust that it retrieved
221: * a filename for us. This mechanism prevents hooks from
222: * trapping ID_BROWSE to customize the dialog and from
223: * trying to figure out what we do after we have the name.
224: */
225:
226: lstrcpy(szTemp, lpCI->szFile); //Copy for reference
227:
228: uRet=UStandardHook(lpCI, hDlg, uMsgBrowse, OLEUI_CCHPATHMAX
229: , (LONG)(LPSTR)lpCI->szFile);
230:
231: dwOfnFlags = OFN_FILEMUSTEXIST;
232: // dont show the help button: easiest fix for #4567 since there is no hook proc
233: // if (lpCI->lpOCI->dwFlags & CIF_SHOWHELP)
234: // dwOfnFlags |= OFN_SHOWHELP;
235:
236: if (0==uRet)
237: uRet=(BOOL)Browse(hDlg, lpCI->szFile, NULL, OLEUI_CCHPATHMAX, IDS_ICONFILTERS, dwOfnFlags);
238:
239: /*
240: * Only reinitialize if the file changed, so if we got
241: * TRUE from the hook but the user hit Cancel, we don't
242: * spend time unecessarily refilling the list.
243: */
244: if (0!=uRet && 0!=lstrcmpi(szTemp, lpCI->szFile))
245: {
246: CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_FROMFILE);
247: SetDlgItemText(hDlg, ID_FROMFILEEDIT, lpCI->szFile);
248: UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile);
249: UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
250: }
251: }
252: break;
253:
254:
255: case IDOK:
256: /*
257: * If the user pressed enter, compare the current file
258: * and the one we have stored. If they match, then
259: * refill the listbox instead of closing down. This is
260: * so the user can press Enter in the edit control as
261: * they would expect to be able to do.
262: */
263: GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp, sizeof(szTemp));
264:
265: //Check if the file changed at all.
266: if (0!=lstrcmpi(szTemp, lpCI->szFile))
267: {
268: lstrcpy(lpCI->szFile, szTemp);
269: UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile);
270: UpdateResultIcon(lpCI, hDlg, ID_FROMFILE);
271:
272: //Eat this message to prevent focus change.
273: return TRUE;
274: }
275:
276:
277: if ((HWND)LOWORD(lParam) != GetFocus())
278: SetFocus((HWND)LOWORD(lParam));
279:
280: /*
281: * On closing, create a new metafilepict with the
282: * current icon and label, destroying the old structure.
283: *
284: * Since we make a copy of the icon by placing it into
285: * the metafile, we have to make sure we delete the
286: * icon in the current field. When the listbox is
287: * destroyed WM_DELETEITEMs will clean it up appropriately.
288: */
289:
290: hIcon=(HICON)SendDlgItemMessage(hDlg, ID_RESULTICON
291: , STM_GETICON, 0, 0L);
292:
293: /*
294: * If default is selected then we get the source
295: * information from registrion database for the
296: * current class to put in the metafile. If current
297: * is selected the we just retrieve the original file
298: * again and recreate the metafile. If from file is
299: * selected we use the current filename from the
300: * control and the current listbox selection.
301: */
302:
303: psz=lpCI->szFile;
304:
305: if (lpCI->dwFlags & CIF_SELECTDEFAULT)
306: {
307: psz=lpCI->szDefIconFile;
308: lpCI->iIcon=lpCI->iDefIcon;
309: hIcon=lpCI->hDefIcon;
310: }
311:
312: if (lpCI->dwFlags & CIF_SELECTCURRENT)
313: {
314: //Go get the current icon source back.
315: OleUIMetafilePictExtractIconSource(lpCI->lpOCI->hMetaPict
316: , psz, &lpCI->iIcon);
317: }
318:
319: if (lpCI->dwFlags & CIF_SELECTFROMFILE)
320: {
321: GetDlgItemText(hDlg, ID_FROMFILEEDIT, psz, OLEUI_CCHPATHMAX);
322:
323: lpCI->iIcon=(UINT)SendDlgItemMessage(hDlg
324: , ID_ICONLIST, LB_GETCURSEL, 0, 0L);
325: }
326:
327:
328: //Get the label and go create the metafile
329: GetDlgItemText(hDlg, ID_LABELEDIT, szTemp, sizeof(szTemp));
330:
331: //If psz is NULL (default) we get no source comments.
332: hMetaPict=OleUIMetafilePictFromIconAndLabel(hIcon
333: , szTemp, psz, lpCI->iIcon);
334:
335: //Clean up the current icon that we extracted.
336: hIcon=(HICON)SendDlgItemMessage(hDlg, ID_CURRENTICON
337: , STM_GETICON, 0, 0L);
338: DestroyIcon(hIcon);
339:
340: //Clean up the default icon
341: DestroyIcon(lpCI->hDefIcon);
342:
343: if (NULL==hMetaPict)
344: SendMessage(hDlg, uMsgEndDialog, OLEUI_FALSE, 0L);
345:
346: OleUIMetafilePictIconFree(lpCI->lpOCI->hMetaPict);
347: lpCI->lpOCI->hMetaPict=hMetaPict;
348:
349: lpCI->lpOCI->dwFlags = lpCI->dwFlags;
350:
351: SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
352: break;
353:
354:
355: case IDCANCEL:
356: //Clean up the current icon that we extracted.
357: hIcon=(HICON)SendDlgItemMessage(hDlg, ID_CURRENTICON
358: , STM_GETICON, 0, 0L);
359: DestroyIcon(hIcon);
360:
361: //Clean up the default icon
362: DestroyIcon(lpCI->hDefIcon);
363:
364: //We leave hMetaPict intact on Cancel; caller's responsibility
365: SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
366: break;
367:
368:
369: case ID_OLEUIHELP:
370: PostMessage(lpCI->lpOCI->hWndOwner, uMsgHelp,
371: (WPARAM)hDlg, MAKELPARAM(IDD_CHANGEICON, 0));
372: break;
373: }
374: break;
375: }
376: return FALSE;
377: }
378:
379:
380:
381:
382: /*
383: * FChangeIconInit
384: *
385: * Purpose:
386: * WM_INITIDIALOG handler for the Change Icon dialog box.
387: *
388: * Parameters:
389: * hDlg HWND of the dialog
390: * wParam WPARAM of the message
391: * lParam LPARAM of the message
392: *
393: * Return Value:
394: * BOOL Value to return for WM_INITDIALOG.
395: */
396:
397: BOOL FChangeIconInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
398: {
399: LPCHANGEICON lpCI;
400: LPOLEUICHANGEICON lpOCI;
401: HFONT hFont;
402: HWND hList;
403: UINT cyList;
404: RECT rc, rcG;
405: UINT uID;
406:
407: //1. Copy the structure at lParam into our instance memory.
408: lpCI=(LPCHANGEICON)LpvStandardInit(hDlg, sizeof(CHANGEICON), TRUE, &hFont);
409:
410: //PvStandardInit send a termination to us already.
411: if (NULL==lpCI)
412: return FALSE;
413:
414: //Save the original pointer and copy necessary information.
415: lpOCI=(LPOLEUICHANGEICON)lParam;
416:
417: lpCI->lpOCI =lpOCI;
418: lpCI->dwFlags=lpOCI->dwFlags;
419:
420: //Go extract the icon source from the metafile.
421: OleUIMetafilePictExtractIconSource(lpOCI->hMetaPict, lpCI->szFile, &lpCI->iIcon);
422:
423: //Go extract the icon and the label from the metafile
424: OleUIMetafilePictExtractLabel(lpOCI->hMetaPict, lpCI->szLabel, OLEUI_CCHLABELMAX, NULL);
425: lpCI->hCurIcon=OleUIMetafilePictExtractIcon(lpOCI->hMetaPict);
426:
427: //2. If we got a font, send it to the necessary controls.
428: if (NULL!=hFont)
429: {
430: SendDlgItemMessage(hDlg, ID_RESULTLABEL, WM_SETFONT
431: , (WPARAM)hFont, 0L);
432: }
433:
434:
435: //3. Show or hide the help button
436: if (!(lpCI->dwFlags & CIF_SHOWHELP))
437: StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE);
438:
439:
440: /*
441: * 4. Set text limits and initial control values. If we're given
442: * an intial label we set it in the edit and static controls.
443: * If we don't, then we copy the default contents of the static
444: * control into the edit control, meaning that only the default
445: * static control string need be localized.
446: */
447:
448: SendDlgItemMessage(hDlg, ID_LABELEDIT, EM_LIMITTEXT, OLEUI_CCHLABELMAX, 0L);
449: SendDlgItemMessage(hDlg, ID_FROMFILEEDIT, EM_LIMITTEXT, OLEUI_CCHPATHMAX, 0L);
450: SetDlgItemText(hDlg, ID_FROMFILEEDIT, lpCI->szFile);
451:
452: //Copy the label text into the edit and static controls.
453: SetDlgItemText(hDlg, ID_LABELEDIT, lpCI->szLabel);
454: SetDlgItemText(hDlg, ID_RESULTLABEL, lpCI->szLabel);
455:
456:
457: lpCI->hDefIcon = NULL;
458:
459: if (lpCI->dwFlags & CIF_USEICONEXE)
460: {
461: lpCI->hDefIcon = ExtractIcon(ghInst, lpCI->lpOCI->szIconExe, 0);
462:
463: if (NULL != lpCI->hDefIcon)
464: {
465: lstrcpy(lpCI->szDefIconFile, lpCI->lpOCI->szIconExe);
466: lpCI->iDefIcon = 0;
467: }
468: }
469:
470:
471: if (NULL == lpCI->hDefIcon)
472: {
473: HGLOBAL hMetaPict;
474:
475: hMetaPict = GetIconOfClass(ghInst,
476: &lpCI->lpOCI->clsid,
477: NULL,
478: TRUE);
479:
480: lpCI->hDefIcon = OleUIMetafilePictExtractIcon(hMetaPict);
481:
482: OleUIMetafilePictExtractIconSource(hMetaPict,
483: lpCI->szDefIconFile,
484: &lpCI->iDefIcon);
485:
486: OleUIMetafilePictIconFree(hMetaPict);
487: }
488:
489:
490: //Initialize all the icon displays.
491: SendDlgItemMessage(hDlg, ID_CURRENTICON, STM_SETICON
492: , (WPARAM)lpCI->hCurIcon, 0L);
493: SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_SETICON
494: , (WPARAM)lpCI->hDefIcon, 0L);
495: SendDlgItemMessage(hDlg, ID_RESULTICON, STM_SETICON
496: , (WPARAM)lpCI->hCurIcon, 0L);
497:
498:
499: /*
500: * 5. Since we cannot predict the size of icons on any display,
501: * we have to resize the icon listbox to the size of an icon
502: * (plus padding), a scrollbar, and two borders (top & bottom).
503: */
504: cyList=GetSystemMetrics(SM_CYICON)+GetSystemMetrics(SM_CYHSCROLL)
505: +GetSystemMetrics(SM_CYBORDER)*2+CYICONPAD;
506:
507: hList=GetDlgItem(hDlg, ID_ICONLIST);
508: GetClientRect(hList, &rc);
509: SetWindowPos(hList, NULL, 0, 0, rc.right, cyList
510: , SWP_NOMOVE | SWP_NOZORDER);
511:
512: //Set the columns in this multi-column listbox to hold one icon
513: SendMessage(hList, LB_SETCOLUMNWIDTH
514: , GetSystemMetrics(SM_CXICON)+CXICONPAD,0L);
515:
516: /*
517: * 5a. If the listbox expanded below the group box, then size
518: * the groupbox down, move the label static and exit controls
519: * down, and expand the entire dialog appropriately.
520: */
521:
522: GetWindowRect(hList, &rc);
523: GetWindowRect(GetDlgItem(hDlg, ID_GROUP), &rcG);
524:
525: if (rc.bottom > rcG.bottom)
526: {
527: //Calculate amount to move things down.
528: cyList=(rcG.bottom-rcG.top)-(rc.bottom-rc.top-cyList);
529:
530: //Expand the group box.
531: rcG.right -=rcG.left;
532: rcG.bottom-=rcG.top;
533: SetWindowPos(GetDlgItem(hDlg, ID_GROUP), NULL, 0, 0
534: , rcG.right, rcG.bottom+cyList
535: , SWP_NOMOVE | SWP_NOZORDER);
536:
537: //Expand the dialog box.
538: GetClientRect(hDlg, &rc);
539: SetWindowPos(hDlg, NULL, 0, 0, rc.right, rc.bottom+cyList
540: , SWP_NOMOVE | SWP_NOZORDER);
541:
542: //Move the label and edit controls down.
543: GetClientRect(GetDlgItem(hDlg, ID_LABEL), &rc);
544: SetWindowPos(GetDlgItem(hDlg, ID_LABEL), NULL, 0, cyList
545: , rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER);
546:
547: GetClientRect(GetDlgItem(hDlg, ID_LABELEDIT), &rc);
548: SetWindowPos(GetDlgItem(hDlg, ID_LABELEDIT), NULL, 0, cyList
549: , rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER);
550: }
551:
552:
553: /*
554: * 6. Select Current, Default, or From File radiobuttons appropriately.
555: * The CheckRadioButton call sends WM_COMMANDs which handle
556: * other actions. Note that if we check From File, which
557: * takes an icon from the list, we better fill the list.
558: * This will also fill the list even if default is selected.
559: */
560:
561: if (0!=UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile))
562: {
563: //If szFile worked, then select the source icon in the listbox.
564: SendDlgItemMessage(hDlg, ID_ICONLIST, LB_SETCURSEL, lpCI->iIcon, 0L);
565: }
566:
567:
568: if (lpCI->dwFlags & CIF_SELECTCURRENT)
569: CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_CURRENT);
570: else
571: {
572: uID=(lpCI->dwFlags & CIF_SELECTFROMFILE) ? ID_FROMFILE : ID_DEFAULT;
573: CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, uID);
574: }
575:
576: //7. Call the hook with lCustData in lParam
577: UStandardHook(lpCI, hDlg, WM_INITDIALOG, wParam, lpOCI->lCustData);
578: return TRUE;
579: }
580:
581:
582:
583:
584:
585: /*
586: * UFillIconList
587: *
588: * Purpose:
589: * Given a listbox and a filename, attempts to open that file and
590: * read all the icons that exist therein, adding them to the listbox
591: * hList as owner-draw items. If the file does not exist or has no
592: * icons, then you get no icons and an appropriate warning message.
593: *
594: * Parameters:
595: * hDlg HWND of the dialog containing the listbox.
596: * idList UINT identifier of the listbox to fill.
597: * pszFile LPSTR of the file from which to extract icons.
598: *
599: * Return Value:
600: * UINT Number of items added to the listbox. 0 on failure.
601: */
602:
603: UINT UFillIconList(HWND hDlg, UINT idList, LPSTR pszFile)
604: {
605: HWND hList;
606: UINT i;
607: UINT cIcons=0;
608: HCURSOR hCur;
609: HICON hIcon;
610: OFSTRUCT of;
611:
612: if (NULL==hDlg || !IsWindow(hDlg) || NULL==pszFile)
613: return 0;
614:
615: hList=GetDlgItem(hDlg, idList);
616:
617: if (NULL==hList)
618: return 0;
619:
620: //Clean out the listbox.
621: SendMessage(hList, LB_RESETCONTENT, 0, 0L);
622:
623: //If we have an empty string, just exit leaving the listbox empty as well
624: if (0==lstrlen(pszFile))
625: return 0;
626:
627: //Turn on the hourglass
628: hCur=HourGlassOn();
629:
630: //Check if the file is valid.
631: if (HFILE_ERROR!=OpenFile(pszFile, &of, OF_EXIST))
632: {
633: #ifdef EXTRACTICONWORKS
634: //Get the icon count for this file.
635: cIcons=(UINT)ExtractIcon(ghInst, pszFile, (UINT)-1);
636: #else
637: /*
638: * ExtractIcon in Windows 3.1 with -1 eats a selector, leaving an
639: * extra global memory object around for this applciation. Since
640: * changing icons may happen very often with all OLE apps in
641: * the system, we have to work around it. So we'll say we
642: * have lots of icons and just call ExtractIcon until it
643: * fails. We check if there's any around by trying to get
644: * the first one.
645: */
646: cIcons=0xFFFF;
647:
648: hIcon=ExtractIcon(ghInst, pszFile, 0);
649:
650: //Fake a failure with cIcons=0, or cleanup hIcon from this test.
651: if (32 > (UINT)hIcon)
652: cIcons=0;
653: else
654: DestroyIcon(hIcon);
655: #endif
656:
657: if (0!=cIcons)
658: {
659: SendMessage(hList, WM_SETREDRAW, FALSE, 0L);
660:
661: for (i=0; i<cIcons; i++)
662: {
663: hIcon=ExtractIcon(ghInst, pszFile, i);
664:
665: if (32 < (UINT)hIcon)
666: SendMessage(hList, LB_ADDSTRING, 0, (LONG)(UINT)hIcon);
667: #ifndef EXTRACTICONWORKS
668: else
669: {
670: //ExtractIcon failed, so let's leave now.
671: break;
672: }
673: #endif
674: }
675:
676: //Force complete repaint
677: SendMessage(hList, WM_SETREDRAW, TRUE, 0L);
678: InvalidateRect(hList, NULL, TRUE);
679:
680: //Select an icon
681: SendMessage(hList, LB_SETCURSEL, 0, 0L);
682: }
683: else
684: ErrorWithFile(hDlg, ghInst, IDS_CINOICONSINFILE, pszFile, MB_OK);
685: }
686: else
687: OpenFileError(hDlg, of.nErrCode, pszFile);
688:
689: HourGlassOff(hCur);
690: return cIcons;
691: }
692:
693:
694:
695:
696: /*
697: * FDrawListIcon
698: *
699: * Purpose:
700: * Handles WM_DRAWITEM for the icon listbox.
701: *
702: * Parameters:
703: * lpDI LPDRAWITEMSTRUCT from WM_DRAWITEM
704: *
705: * Return Value:
706: * BOOL TRUE if we did anything, FALSE if there are no items
707: * in the list.
708: */
709:
710: BOOL FDrawListIcon(LPDRAWITEMSTRUCT lpDI)
711: {
712: COLORREF cr;
713:
714: /*
715: * If there are no items in the list, then itemID is negative according
716: * to the Win3.1 SDK. Unfortunately DRAWITEMSTRUCT has an unsigned int
717: * for this field, so we need the typecast to do a signed comparison.
718: */
719: if ((int)lpDI->itemID < 0)
720: return FALSE;
721:
722: /*
723: * For selection or draw entire case we just draw the entire item all
724: * over again. For focus cases, we only call DrawFocusRect.
725: */
726:
727: if (lpDI->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))
728: {
729: //Clear background and draw the icon.
730: if (lpDI->itemState & ODS_SELECTED)
731: cr=SetBkColor(lpDI->hDC, GetSysColor(COLOR_HIGHLIGHT));
732: else
733: cr=SetBkColor(lpDI->hDC, GetSysColor(COLOR_WINDOW));
734:
735: //Draw a cheap rectangle.
736: ExtTextOut(lpDI->hDC, 0, 0, ETO_OPAQUE, &lpDI->rcItem
737: , NULL, 0, NULL);
738:
739: DrawIcon(lpDI->hDC, lpDI->rcItem.left+(CXICONPAD/2)
740: , lpDI->rcItem.top+(CYICONPAD/2)
741: , (HICON)LOWORD(lpDI->itemData));
742:
743: //Restore original background for DrawFocusRect
744: SetBkColor(lpDI->hDC, cr);
745: }
746:
747: //Always change focus on the focus action.
748: if (lpDI->itemAction & ODA_FOCUS || lpDI->itemState & ODS_FOCUS)
749: DrawFocusRect(lpDI->hDC, &lpDI->rcItem);
750:
751: return TRUE;
752: }
753:
754:
755:
756:
757:
758: /*
759: * UpdateResultIcon
760: *
761: * Purpose:
762: * Updates the result icon using the current icon in the default display
763: * or the icon listbox depending on fFromDefault.
764: *
765: * Parameters:
766: * lpCI LPCHANGEICON containing dialog flags.
767: * hDlg HWND of the dialog
768: * uID UINT identifying the radiobutton selected.
769: *
770: * Return Value:
771: * None
772: */
773:
774: void UpdateResultIcon(LPCHANGEICON lpCI, HWND hDlg, UINT uID)
775: {
776: UINT iSel;
777: LONG lTemp=LB_ERR;
778:
779: lpCI->dwFlags &= ~(CIF_SELECTCURRENT | CIF_SELECTDEFAULT | CIF_SELECTFROMFILE);
780:
781: switch (uID)
782: {
783: case ID_CURRENT:
784: lTemp=SendDlgItemMessage(hDlg, ID_CURRENTICON, STM_GETICON, 0, 0L);
785: lpCI->dwFlags |= CIF_SELECTCURRENT;
786: break;
787:
788: case ID_DEFAULT:
789: lTemp=SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_GETICON, 0, 0L);
790: lpCI->dwFlags |= CIF_SELECTDEFAULT;
791: break;
792:
793: case ID_FROMFILE:
794: //Get the selected icon from the list and place it in the result
795: lpCI->dwFlags |= CIF_SELECTFROMFILE;
796:
797: iSel=(UINT)SendDlgItemMessage(hDlg, ID_ICONLIST, LB_GETCURSEL, 0, 0L);
798: if ((UINT)LB_ERR==iSel)
799: lTemp=SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_GETICON, 0, 0L);
800: else
801: SendDlgItemMessage(hDlg, ID_ICONLIST, LB_GETTEXT, iSel
802: , (LPARAM)(LPLONG)&lTemp);
803:
804: break;
805: }
806:
807: if ((LONG)LB_ERR!=lTemp)
808: SendDlgItemMessage(hDlg, ID_RESULTICON, STM_SETICON, LOWORD(lTemp), 0L);
809: return;
810: }
811:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.