Chris Herring submitted the following code to draw the associated icon for any document on a button. For example: you created a button to open a file like "c:\invoices\abc001.doc", the file extension "doc" is associated with MS-Word so you want the icon for Word-documents displayed on the Progress button.
The remainder of the text is from Chris. As you see, he has some issues left. If you know the solution, please click the "Edit"-link near the bottom of this page to help out.
There were two ways I found to add the icon, using SendMessageA and ImageList_Draw. SendMessageA works ok except it suffers from the same limitations and the toggle button - can't remove focus. ImageList_Draw seems to be able to draw the icon on progress widgets that have the HWND attribute( at least the button and frame anyway ) but the image is release whenever the display for the image is refreshed. On the plus side it would work with flat buttons if you could get the image to stay. Anyway I've put some of my code below. Only thing that I'm aware of that is not entirely correct is the size of the fileinfo memptr regarding the last two string parameters. I wasn't sure of the size so I set them to 1 which only returns the first char of the string if the display name and type tags are added to the flag.
&GLOBAL-DEFINE GWL_STYLE -16 &GLOBAL-DEFINE BM_SETIMAGE 247 &GLOBAL-DEFINE IMAGE_ICON 1 &GLOBAL-DEFINE SHGFI_ICON 256 &GLOBAL-DEFINE SHGFI_SYSICONINDEX 16384 &GLOBAL-DEFINE SHGFI_USEFILEATTRIBUTES 16 &GLOBAL-DEFINE FILE_ATTRIBUTE_NORMAL 128 &GLOBAL-DEFINE BS_ICON 64 PROCEDURE SHGetFileInfo EXTERNAL 'shell32': DEFINE INPUT PARAMETER pszPath AS CHARACTER. DEFINE INPUT PARAMETER dwFileAttributes AS LONG. DEFINE OUTPUT PARAMETER SBFileInfo AS MEMPTR. DEFINE INPUT PARAMETER cbSizeFileInfo AS LONG. DEFINE INPUT PARAMETER uFlags AS LONG. DEFINE RETURN PARAMETER ReturnValue AS LONG. END PROCEDURE. PROCEDURE ImageList_Draw EXTERNAL "comctl32": DEFINE INPUT PARAMETER himl AS LONG. DEFINE INPUT PARAMETER iIndex AS LONG. DEFINE INPUT PARAMETER hdc AS LONG. DEFINE INPUT PARAMETER X AS LONG. DEFINE INPUT PARAMETER Y AS LONG. DEFINE INPUT PARAMETER iStyle AS LONG. DEFINE RETURN PARAMETER lBool AS LONG. END PROCEDURE. PROCEDURE setButton : /*-- Purpose: gets the icon from a program, file, or extension and draws the icon on the specified button Notes: the button must not be flat or no-focus ------------------------------------------------------------------------------*/ DEFINE INPUT PARAMETER iHwnd AS INTEGER NO-UNDO. DEFINE INPUT PARAMETER iphButton AS HANDLE NO-UNDO. DEFINE INPUT PARAMETER pcProgram AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER plExtension AS LOGICAL NO-UNDO. DEFINE VARIABLE iSize AS INTEGER NO-UNDO. DEFINE VARIABLE fileinfo AS MEMPTR NO-UNDO. DEFINE VARIABLE iFlags AS INTEGER NO-UNDO. DEFINE VARIABLE iReturn AS INTEGER NO-UNDO. DEFINE VARIABLE hIcon AS INTEGER NO-UNDO. DEFINE VARIABLE iIcon AS INTEGER NO-UNDO. DEFINE VARIABLE iAttr AS INTEGER NO-UNDO. DEFINE VARIABLE cDName AS CHARACTER NO-UNDO. DEFINE VARIABLE cType AS CHARACTER NO-UNDO. DEFINE VARIABLE iStyles AS INTEGER NO-UNDO. DEFINE VARIABLE iOldIcon AS INTEGER NO-UNDO. SET-SIZE(fileinfo) = 4 + 4 + 4 + 1 + 1. iSize = GET-SIZE(fileinfo). IF iSize NE 0 THEN DO: /*RUN SHGetFileInfo( "C:\Program Files\Internet Explorer\IEXPLORE.EXE", 0, OUTPUT fileinfo, iSize, iFlags, OUTPUT lReturn ).*/ /*RUN SHGetFileInfo( ".html", 128, OUTPUT fileinfo, iSize, iFlags, OUTPUT lReturn ).*/ IF plExtension THEN DO: iFlags = {&SHGFI_ICON} + {&SHGFI_USEFILEATTRIBUTES}. RUN SHGetFileInfo( pcProgram, {&FILE_ATTRIBUTE_NORMAL}, OUTPUT fileinfo, iSize, iFlags, OUTPUT iReturn ). END. ELSE DO: iFlags = {&SHGFI_ICON}. RUN SHGetFileInfo( pcProgram, 0, OUTPUT fileinfo, iSize, iFlags, OUTPUT iReturn ). END. hIcon = GET-LONG(fileinfo, 1). iIcon = GET-LONG(fileinfo, 5). iAttr = GET-LONG(fileinfo, 9). cDName = GET-STRING(fileinfo, 13). cType = GET-STRING(fileinfo, 14). SET-SIZE(fileinfo) = 0. END. RUN GetWindowLongA(iHwnd, {&GWL_STYLE}, OUTPUT iStyles). IF iphButton:PRIVATE-DATA EQ ? THEN ASSIGN iStyles = iStyles + {&BS_ICON} iphButton:PRIVATE-DATA = "loaded". ELSE ASSIGN iStyles = iStyles. RUN SetWindowLongA(iHwnd, {&GWL_STYLE}, iStyles, OUTPUT iStyles). RUN SendMessageA( iHwnd, {&BM_SETIMAGE}, {&IMAGE_ICON}, hIcon, OUTPUT iOldIcon). END PROCEDURE.