Solved

Application Icon

Posted on 2001-09-07
11
359 Views
Last Modified: 2010-04-06
Hi...
How do I retrieve a copy of a windows icon ?
Similar to how is it done by ZoneAlarm or TrayMin.
0
Comment
Question by:CyberKnight
  • 5
  • 3
  • 2
  • +1
11 Comments
 
LVL 1

Expert Comment

by:Dennis9
ID: 6463735
Try this:

procedure TForm1.FormCreate(Sender: TObject);
begin
Self.Icon.Handle := LoadIcon(0, IDI_WARNING);
end;

{***Other icons***
IDI_WARNING                     - yellow triangle
IDI_APPLICATION                 - application icon
IDI_ASTERISK                    - ! icon
IDI_EXCLAMATION (= IDI_WARNING) - yellow triangle
IDI_HAND                        - Red cross
IDI_QUESTION                    - ? icon
IDI_WINLOGO                     - Windows icon
}


Dennis
0
 

Author Comment

by:CyberKnight
ID: 6464051
Hi Dennis
Nope, this is not what Im looking for ... let me try to be a little clearer....

I want to get the icon of "another application".

For example... if "Calculator" is running, I can retrieve its window handle, but I also want a copy of its "calculator" icon. .... how do i do this..?

0
 
LVL 6

Expert Comment

by:edey
ID: 6464095
I don't think you'd do that with a handle from a running app, rather with the file name - from win32.hlp:


The ExtractIcon function retrieves the handle of an icon from the specified executable file, dynamic-link library (DLL), or icon file.

HICON ExtractIcon(

    HINSTANCE hInst,     // instance handle
    LPCTSTR lpszExeFileName,     // filename of file with icon
    UINT nIconIndex      // index of icon to extract
   );    
 

Parameters

hInst

Identifies the instance of the application calling the function.

lpszExeFileName

Points to a null-terminated string specifying the name of an executable file, DLL, or icon file.

nIconIndex

Specifies the index of the icon to retrieve. If this value is 0, the function returns the handle of the first icon in the specified file. If this value is -1, the function returns the total number of icons in the specified file.

 

Return Values

If the function succeeds, the return value is the handle to an icon. If the file specified was not an executable file, DLL, or icon file, the return is 1. If no icons were found in the file, the return value is NULL.




GL
Mike
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:CyberKnight
ID: 6464115
Ok, Mike, .. maybe that is the only way to really get the icon of a window... currently Im using this way (but it only gets the icon of some windows).

IconHandle:=SendMessage(WindowHandle,WM_GETICON,1,0);
(or something to that effect - recalling from memory hehehe)

Mike,...how do I go about getting the file name of the window (all I have is the window handle) ????
0
 
LVL 6

Expert Comment

by:edey
ID: 6464177
I found this snippet:

var
  ModuleHandle : THandle;
  FileName : PChar;
begin
  FileName := StrAlloc(255);
  ModuleHandle := GetClassLong(WindowHandle, GCL_HMODULE);
  GetModuleFileName(ModuleHandle, FileName, 255);
  // FileName should contain the executable or dll name and path
  StrDispose(FileName);
end;


but I haven't tested it yet.

GL
Mike
0
 

Author Comment

by:CyberKnight
ID: 6466431
The snippet doesnt seem to retrieve the correct file name ..?
This is what Im currently doing....



procedure TForm1.Button1Click(Sender: TObject);
var
 ModuleHandle : THandle;
 FileName : array[0..255] of char;
 Hi1,hi2:Hicon;
 c:integer;
begin
 WindowHandle:=FindWindow(nil,'Calculator');

 ModuleHandle := GetClassLong(WindowHandle, GCL_HMODULE);
 GetModuleFileName(ModuleHandle, FileName, 200);
 showmessage(filename); // the file name seems to be incorrect

 ExtractIconEx(FileName,0,hi1,hi2,c);
 DrawIcon(form1.canvas.handle,0,0,hi1);
 DrawIcon(form1.canvas.handle,0,50,hi2);
End;
0
 
LVL 4

Expert Comment

by:jeurk
ID: 6468602
I'll send you a sample tomorrow. Doing exactly that...
0
 
LVL 4

Accepted Solution

by:
jeurk earned 100 total points
ID: 6475907
Hi, here it is...
Let me know if you have problems in using it...
John.

ps: a lot of work for only 10 points...

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function GetIconFromWindow( h:hwnd ; bBigIcon:boolean ):HICON;
    procedure GetWinClassName;
  end;

var
  Form1: TForm1;
  fWindowCaption: string;
  fWindowClass: string;

implementation

uses variants;

{$R *.DFM}

{ TForm1 }

function getCMChildWinHandle(WinHandle: THandle; FoundWindow: PHandle): BOOL; stdcall;
var
  Buffer: array[0..50] of Char;
begin
  Result := True;
  GetClassName(WinHandle, Buffer, SizeOf(Buffer) - 1);
  if pos(PChar(fWindowClass), Buffer) <> 0 then
  begin
    GetWindowText(WinHandle, Buffer, SizeOf(Buffer) - 1);
    if Pos(fWindowCaption, Buffer) <> 0 then
    begin
      FoundWindow^ := WinHandle;
      Result := False;
    end;
  end;
end;

function getWindowHandle(WindowCaption: string; WindowClass: string): THandle;
begin //we should try to lowercas everything one day.
  fWindowCaption := WindowCaption;
  fWindowClass := WindowClass;
  result := 0;
  EnumWindows(@getCMChildWinHandle, Integer(@result));
end;

procedure TForm1.GetWinClassName;
Var
 ClassName : Array[0..255] of Char;
 WinClass  : TWndClass;

  ClassRegistered: Boolean;
  TempClass: TWndClass;
  Params: TCreateParams;
  TempClassEx: TWndClassEx;

  h:THandle;

begin
// 1. Using GetClassName API function
 GetClassName(form1.Handle, ClassName, 256);
 Edit1.Text := StrPas(ClassName);
// 2. Using GetClassInfo API function
 GetClassInfo(form1.Handle, ClassName, WinClass);

 //Edit1.Text := WinClass.lpszClassName;


 h := getWindowHandle('Untitled - Notepad', 'Notepad');
 image1.Picture.Icon.Handle := GetIconFromWindow(h, true);

ClassRegistered := GetClassInfoEx(h,
                         'Notepad', TempClassEx);
if ClassRegistered then
  image1.Canvas.Handle := TempClassEx.hIcon;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
GetWinClassName;
end;

function TForm1.GetIconFromWindow(h: hwnd; bBigIcon: boolean): HICON;
var
          hi: cardinal;
begin
  if(h <> null) then
  begin
    SendMessageTimeout( h, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG, 1000, hi );
    if( hi = 0 ) then hi := GetClassLong( h, GCL_HICONSM );
    if( hi = 0 ) then  SendMessageTimeout( h, WM_QUERYDRAGICON, 0, 0, SMTO_ABORTIFHUNG, 1000, hi );
    if( hi = 0 ) then  SendMessageTimeout( h, WM_GETICON, ICON_BIG, 0, SMTO_ABORTIFHUNG, 1000, hi );
    if( hi = 0 ) then  hi := GetClassLong( h, GCL_HICONSM );
  end;
  result := hi;
end;

end.
0
 

Author Comment

by:CyberKnight
ID: 6478739
Hi John, ...

yes it is a lot of work for 10 points ....(but then again, U did say that U would post it the "next" day... - kidding, I am increasing the points :)

And it WORKS !! (well) !!
Just 1 comment... I think you meant for the "last" GetClassLong line to be this :-

if( hi = 0 ) then  hi := GetClassLong( h, GCL_HICON );
(coz U duplicated that line).... rite ?
0
 

Author Comment

by:CyberKnight
ID: 6479084
Great ! Thanx!
0
 
LVL 4

Expert Comment

by:jeurk
ID: 6480448
Hi, I'm glad it's working (I knew it in fact;)

About the points, let's say that you are lucky and that
I already knew how to do it ;)
But thank you anyway.

Anyway, about the last line, you have to leave it because it's there in the case the first technique is not working...
some application do not respond to the first message. that's why we try again by first sending a sencond message and then try again...
At leaast that's what I found out by experience...
ICQ are such shitty application...
Well.
Have fun.
John
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question