VB3 How To Extract a Windows Program Icon--Running or NotID: Q88944
|
The example program included below demonstrates how to extract an icon from a Windows program, whether it is currently running or not. There are two different techniques depending on whether the program is run in Windows version 3.0 or 3.1. The API function ExtractIcon, introduced in Windows version 3.1, simplifies the process of extracting the icon. In Windows version 3.0, a different approach is required. Both methods are illustrated below.
The example program shown below displays the icon of an application in a
picture box. The example demonstrates the handling of the hDC property of
the picture box control, specifically the relationship between the Refresh
method, the Image property, and the AutoRedraw property. The code in the
Command3_Click event demonstrates how to transfer the captured icon image
to the Picture property of a picture box (Picture2).
' API declarations used in Windows version 3.0 method.
Declare Function GetActiveWindow Lib "User" () As Integer
Declare Function PostMessage Lib "User" (ByVal hWnd As Integer,
ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Any)
As Integer
Declare Function FindWindow Lib "User" (ByVal lpClassName As Any,
ByVal lpWindowName As Any) As Integer
Declare Function LoadLibrary Lib "Kernel" (ByVal lpLibFileName
As String) As Integer
Declare Function GetWindowWord Lib "User" (ByVal hWnd As Integer,
ByVal nIndex As Integer) As Integer
Declare Function LoadIcon Lib "User" (ByVal hInstance As Integer,
ByVal lpIconName As Any) As Integer
' API declarations used in Windows version 3.1 method.
Declare Function GetModuleHandle Lib "Kernel" (ByVal lpModuleName
As String) As Integer
Declare Function GetClassWord Lib "User" (ByVal hWnd As Integer,
ByVal nIndex As Integer) As Integer
Declare Function ExtractIcon Lib "SHELL" (ByVal hInst As Integer,
ByVal lpszexename As String, ByVal hIcon As Integer) As Integer
' API declaration used by both Windows version 3.0 and 3.1 methods.
Declare Function DrawIcon Lib "User" (ByVal hDC As Integer, ByVal x
As Integer, ByVal Y As Integer, ByVal hIcon As Integer) As Integer
' Window field offsets for GetClassWord() and GetWindowWord().
Const GWW_HINSTANCE = (-6)
Const GCW_HMODULE = (-16)
' Constants for SendMessage and PostMessage.
Const WM_CLOSE = &H10
' If using Visual Basic version 1.0, remove the single quotation mark
' from the following line of code:
' Const NULL = 0&
Sub Form_Load ()
Command1.Caption = " 3.0 method "
Command2.Caption = " 3.1 method "
Command3.Caption = " Transfer "
Form1.Caption = " Example of Extracting an Icon"
Form1.Width = Screen.Width * 2 / 3
Form1.Height = Screen.Height / 2
' Center the form on the screen.
' Enter the following two lines as one, single line:
Form1.Move (Screen.Width - Form1.Width) / 2,
(Screen.Height - Form1.Height) / 2
' Size and position the controls dynamically at run time.
' Enter the following two lines as one, single line:
Picture1.Move 0, 0, Form1.Width / 2,
Form1.Height - Command1.Height * 4
' Enter the following two lines as one, single line:
Picture2.Move Form1.Width / 2, 0, Form1.Width,
Form1.Height - Command2.Height * 4
' Enter the following two lines as one, single line:
Command1.Move (Form1.Width / 2 - Command1.Width) / 2,
Form1.Height - Command1.Height * 4
' Enter the following two lines as one, single line:
Command2.Move (Form1.Width / 2 - Command1.Width) / 2,
Form1.Height - Command1.Height * 3
' Enter the following two lines as one, single line:
Command3.Move (Form1.Width * 3 / 2 - Command2.Width) / 2,
Form1.Height - Command2.Height * 4
End Sub
Sub Command1_Click ()
Dim hInstance As Integer, handle As Integer, hIcon As Integer
Picture1.Picture = LoadPicture("") ' clear any previous image
' Three alternative ways to obtain the handle of the top-level window
' of the program whose icon you want to extract:
' Method 1: If the program is currently running and you don't know
' the class name.
' AppActivate ("Program Manager") ' Set focus to application.
' handle = GetActiveWindow() ' Get handle to window.
' Command1.SetFocus ' Return focus to button.
' Method 2: If program is running and you know the class name.
' Handle = FindWindow("Progman", "Program Manager")
' Method 3: If program is not running, use path and filename.
' Not_Running_Way "sysedit.exe" ' Call sub at general level.
' Exit Sub ' Bypass remaining code in this Sub.
' Now you have the handle -- use it to obtain the instance handle.
hInstance = GetWindowWord(handle, GWW_HINSTANCE)
Picture2.Print "3.O method "
Picture2.Print "handle="; Hex$(handle)
Picture2.Print "hInstance= "; Hex$(hInstance) ' Sanity check.
' Iterate through icon resource identifier values
' until you obtain a valid handle to an icon.
Do
hIcon = LoadIcon(hInstance, n&)
n& = n& + 1
Loop Until hIcon <> 0
Picture2.Print "hIcon= "; Hex$(hIcon)
Picture1.AutoRedraw = -1 ' Make hDC point to persistent bitmap.
r = DrawIcon(Picture1.hDC, 19, 19, hIcon) 'Draw the icon.
Picture1.Refresh ' Refresh from persistent bitmap to Picture.
End Sub
Sub Command2_Click ()
Dim myhInst As Integer, hIcon As Integer
Picture1.Picture = LoadPicture("") ' Clear the previous image.
' Listed below are three alternative methods that can be used to
' obtain the hInst of your program's module handle.
' Method 1: Use only with .EXE version of your program.
' myhInst = GetModuleHandle("Project1.exe")
' Method 2: Use only with your program running in the environment.
' myhInst = GetModuleHandle("VB.EXE")
' Method 3: The slick way that works in either case.
myhInst = GetClassWord(hWnd, GCW_HMODULE)
' The path and filename of program to extract icon from.
lpzxExeName$ = "moricons.dll" ' Can also use an .EXE file here.
' Get handle to icon.
hIcon = ExtractIcon(myhInst, lpzxExeName$, 0)
Picture2.Print "3.1 method "
Picture2.Print "myhInst= "; Hex$(myhInst) ' Sanity check.
Picture2.Print "hIcon= "; Hex$(hIcon) ' Sanity check.
Picture1.AutoRedraw = -1 ' Make the picture's hDC point to the
' persistent bitmap.
r% = DrawIcon(Picture1.hDC, 19, 19, hIcon)
Picture1.Refresh ' Cause Windows to paint from the persistent bitmap
' to show the icon.
End Sub
Sub Not_Running_Way (appname As String)
Dim hInstance As Integer, handle As Integer, hIcon As Integer
Dim hWndShelledWindow As Integer
Picture1.Picture = LoadPicture("") ' Clear any previous image.
hInstance = Shell(appname, 2)
Picture2.Print "3.0 method-application not running"
Picture2.Print "hInstance= "; Hex$(hInstance) ' Check return.
r = DoEvents() ' Allow time for shell to complete.
' The following technique is from another article that explains
' how to determine when a shelled process has terminated. It is
' used here to obtain the correct handle to the window of the
' application whose icon is being extracted. The handle is needed
' to close the application after the extraction is complete.
TimeOutPeriod = 5
fTimeOut = 0 ' Set to false.
s! = Timer
Do
r = DoEvents()
hWndShelledWindow = GetActiveWindow()
' Set timeout flag if time has expired.
If Timer - s! > TimeOutPeriod Then fTimeOut = True
Loop While hWndShelledWindow = Form1.hWnd And Not fTimeOut
' If a timeout occurred, display a timeout message and terminate.
If fTimeOut Then
MsgBox "Timeout waiting for shelled application", 16
Exit Sub
End If
' Iterate through icon resource identifier values
' until you obtain a valid handle to an icon.
Do
hIcon = LoadIcon(hInstance, n&)
n& = n& + 1
Loop Until hIcon <> 0
Picture2.Print "HICON= "; Hex$(hIcon)
Picture1.AutoRedraw = -1 ' Make hDC point to persistent bitmap.
r = DrawIcon(Picture1.hDC, 19, 19, hIcon)
Picture2.Print "return from DrawIcon="; r
Picture1.Refresh ' Refresh from persistent bitmap to picture.
' Now post a message to the window to close the application.
r = PostMessage(hWndShelledWindow, WM_CLOSE, NULL, NULL)
Picture2.Print "return from PostMessage="; r
End Sub
Sub Command3_Click ()
' This code transfers the extracted icon's image to Picture2's
' Picture property and demonstrates that DrawIcon assigns the image
' to the hDC of Picture1, which points to the persistent bitmap
' (Image property), not to the Picture property.
Picture2.Picture = LoadPicture("") ' Clear old icon.
Picture2.currenty = 0 ' Reset coordinates for printing
' return values.
Picture2.currentx = 0
Picture2.Picture = Picture1.image ' Transfer persistent bitmap image
' to the Picture property.
End Sub
"Microsoft Windows Software Development Kit Volume 2"
"Microsoft Press Programmer's Reference Library Volume 2"
Additional query words: 2.00 3.00
Keywords : kbcode
Version : 1.00 2.00 3.00
Platform : WINDOWS
Issue type :
Last Reviewed: June 11, 1999