Native Icon Handle. How to obtain ?

  • Thread starter Thread starter Sergey Muschin
  • Start date Start date
S

Sergey Muschin

Hi there,

Is there a way to get a Native Icon Handle for icon, which is an embedded
resource in my project?
Or may be for an icon from Imagelist?

Thank You
 
There is no easy way. Having said this, there is a way to get it via image
list, but it is not for meek.
Basically what you do is create an empty toolbar control and add it to your
form. Then you assign your imagelist to it. Then you use SHFindMenuBar to
get its handle, and then TB_GETIMAGELIST to get hImageList. From there it is
easy to call ImageList_GetIcon to get an icon handle. Then you remove
toolbar. Since this is all done in a single call, toolbar does not have a
chance to show up, nor would it, since it does not have any buttons. The
only problem is that adding/removing control forces the for to repaint once
, but I suspect it can be overcome by doing this on a hidden form.

private int ExtractIcon(ImageList il, int index)

{

Capture = true;

IntPtr hWnd = GetCapture();

Capture = false;

ToolBar tb = new ToolBar();

tb.ImageList = il;

this.Controls.Add(tb);

IntPtr hWndTB = SHFindMenuBar(hWnd);

IntPtr hIL = SendMessage(hWndTB, TB_GETIMAGELIST, 0, 0);

IntPtr hIcon = ImageList_GetIcon(hIL, index, 0);

IntPtr hDC = GetDC(hWnd);

DrawIconEx(hDC, 20, 20, hIcon, 0, 0, 0, IntPtr.Zero, DI_NORMAL);

ReleaseDC(hWnd, hDC);

hIcon = IntPtr.Zero;

this.Controls.Remove(tb);

}


// P/Invokes
const int WM_USER = 0x400;

const int TB_GETIMAGELIST = WM_USER + 49;

const int DI_NORMAL = 3;

[DllImport("coredll")]

extern static IntPtr GetCapture();

[DllImport("coredll")]

extern static IntPtr ImageList_GetIcon(

IntPtr himl,

int i,

uint flags

);

[DllImport("aygshell")]

extern static IntPtr SHFindMenuBar(IntPtr hwnd);

[DllImport("coredll")]

extern static IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int
lParam);

[DllImport("coredll")]

extern static IntPtr GetDC(IntPtr hWnd);

[DllImport("coredll")]

extern static IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("coredll")]

extern static int DrawIconEx(

IntPtr hDC,

int X,

int Y,

IntPtr hIcon,

int cxWidth,

int cyWidth,

int istepIfAniCur,

IntPtr hbrFlickerFreeDraw,

uint diFlags

);
 
Alex, great idea! But since aygshell.dll/SHFindMenuBar can be absent it
would be better to use hidden TreeView with assigned ImageList to it:

treeView1.Capture = true;
IntPtr tv = GetCapture();
treeView1.Capture = false;

IntPtr imageList = SendMessage(tv, TVM_GETIMAGELIST, 0, 0);
IntPtr hIco = ImageList_GetIcon(imageList, 2, 0);

....

const int TVM_GETIMAGELIST = 0x1108;
 
Yes. Even better! The thing about aygshell indeed has bothered me.

--
Alex Feinman
---
Visit http://www.opennetcf.org
Sergey Bogdanov said:
Alex, great idea! But since aygshell.dll/SHFindMenuBar can be absent it
would be better to use hidden TreeView with assigned ImageList to it:

treeView1.Capture = true;
IntPtr tv = GetCapture();
treeView1.Capture = false;

IntPtr imageList = SendMessage(tv, TVM_GETIMAGELIST, 0, 0);
IntPtr hIco = ImageList_GetIcon(imageList, 2, 0);

...

const int TVM_GETIMAGELIST = 0x1108;

--
Sergey Bogdanov
http://www.sergeybogdanov.com

There is no easy way. Having said this, there is a way to get it via
image list, but it is not for meek.
Basically what you do is create an empty toolbar control and add it to
your form. Then you assign your imagelist to it. Then you use
SHFindMenuBar to get its handle, and then TB_GETIMAGELIST to get
hImageList. From there it is easy to call ImageList_GetIcon to get an
icon handle. Then you remove toolbar. Since this is all done in a single
call, toolbar does not have a chance to show up, nor would it, since it
does not have any buttons. The only problem is that adding/removing
control forces the for to repaint once , but I suspect it can be overcome
by doing this on a hidden form.

private int ExtractIcon(ImageList il, int index)

{

Capture = true;

IntPtr hWnd = GetCapture();

Capture = false;

ToolBar tb = new ToolBar();

tb.ImageList = il;

this.Controls.Add(tb);

IntPtr hWndTB = SHFindMenuBar(hWnd);

IntPtr hIL = SendMessage(hWndTB, TB_GETIMAGELIST, 0, 0);

IntPtr hIcon = ImageList_GetIcon(hIL, index, 0);

IntPtr hDC = GetDC(hWnd);

DrawIconEx(hDC, 20, 20, hIcon, 0, 0, 0, IntPtr.Zero, DI_NORMAL);

ReleaseDC(hWnd, hDC);

hIcon = IntPtr.Zero;

this.Controls.Remove(tb);

}


// P/Invokes
const int WM_USER = 0x400;

const int TB_GETIMAGELIST = WM_USER + 49;

const int DI_NORMAL = 3;

[DllImport("coredll")]

extern static IntPtr GetCapture();

[DllImport("coredll")]

extern static IntPtr ImageList_GetIcon(

IntPtr himl,

int i,

uint flags

);

[DllImport("aygshell")]

extern static IntPtr SHFindMenuBar(IntPtr hwnd);

[DllImport("coredll")]

extern static IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int
lParam);

[DllImport("coredll")]

extern static IntPtr GetDC(IntPtr hWnd);

[DllImport("coredll")]

extern static IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("coredll")]

extern static int DrawIconEx(

IntPtr hDC,

int X,

int Y,

IntPtr hIcon,

int cxWidth,

int cyWidth,

int istepIfAniCur,

IntPtr hbrFlickerFreeDraw,

uint diFlags

);
 
You're both nuts. :)

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


Sergey Bogdanov said:
Alex, great idea! But since aygshell.dll/SHFindMenuBar can be absent it
would be better to use hidden TreeView with assigned ImageList to it:

treeView1.Capture = true;
IntPtr tv = GetCapture();
treeView1.Capture = false;

IntPtr imageList = SendMessage(tv, TVM_GETIMAGELIST, 0, 0);
IntPtr hIco = ImageList_GetIcon(imageList, 2, 0);

...

const int TVM_GETIMAGELIST = 0x1108;

--
Sergey Bogdanov
http://www.sergeybogdanov.com

There is no easy way. Having said this, there is a way to get it via
image list, but it is not for meek.
Basically what you do is create an empty toolbar control and add it to
your form. Then you assign your imagelist to it. Then you use
SHFindMenuBar to get its handle, and then TB_GETIMAGELIST to get
hImageList. From there it is easy to call ImageList_GetIcon to get an
icon handle. Then you remove toolbar. Since this is all done in a single
call, toolbar does not have a chance to show up, nor would it, since it
does not have any buttons. The only problem is that adding/removing
control forces the for to repaint once , but I suspect it can be overcome
by doing this on a hidden form.

private int ExtractIcon(ImageList il, int index)

{

Capture = true;

IntPtr hWnd = GetCapture();

Capture = false;

ToolBar tb = new ToolBar();

tb.ImageList = il;

this.Controls.Add(tb);

IntPtr hWndTB = SHFindMenuBar(hWnd);

IntPtr hIL = SendMessage(hWndTB, TB_GETIMAGELIST, 0, 0);

IntPtr hIcon = ImageList_GetIcon(hIL, index, 0);

IntPtr hDC = GetDC(hWnd);

DrawIconEx(hDC, 20, 20, hIcon, 0, 0, 0, IntPtr.Zero, DI_NORMAL);

ReleaseDC(hWnd, hDC);

hIcon = IntPtr.Zero;

this.Controls.Remove(tb);

}


// P/Invokes
const int WM_USER = 0x400;

const int TB_GETIMAGELIST = WM_USER + 49;

const int DI_NORMAL = 3;

[DllImport("coredll")]

extern static IntPtr GetCapture();

[DllImport("coredll")]

extern static IntPtr ImageList_GetIcon(

IntPtr himl,

int i,

uint flags

);

[DllImport("aygshell")]

extern static IntPtr SHFindMenuBar(IntPtr hwnd);

[DllImport("coredll")]

extern static IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int
lParam);

[DllImport("coredll")]

extern static IntPtr GetDC(IntPtr hWnd);

[DllImport("coredll")]

extern static IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("coredll")]

extern static int DrawIconEx(

IntPtr hDC,

int X,

int Y,

IntPtr hIcon,

int cxWidth,

int cyWidth,

int istepIfAniCur,

IntPtr hbrFlickerFreeDraw,

uint diFlags

);
 
Yes, but we knew that all along... Besides this piece of code has been
sitting on my machine from the Callbacks days. I'm much saner now

--
Alex Feinman
---
Visit http://www.opennetcf.org
Chris Tacke said:
You're both nuts. :)

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate


Sergey Bogdanov said:
Alex, great idea! But since aygshell.dll/SHFindMenuBar can be absent it
would be better to use hidden TreeView with assigned ImageList to it:

treeView1.Capture = true;
IntPtr tv = GetCapture();
treeView1.Capture = false;

IntPtr imageList = SendMessage(tv, TVM_GETIMAGELIST, 0, 0);
IntPtr hIco = ImageList_GetIcon(imageList, 2, 0);

...

const int TVM_GETIMAGELIST = 0x1108;

--
Sergey Bogdanov
http://www.sergeybogdanov.com

There is no easy way. Having said this, there is a way to get it via
image list, but it is not for meek.
Basically what you do is create an empty toolbar control and add it to
your form. Then you assign your imagelist to it. Then you use
SHFindMenuBar to get its handle, and then TB_GETIMAGELIST to get
hImageList. From there it is easy to call ImageList_GetIcon to get an
icon handle. Then you remove toolbar. Since this is all done in a single
call, toolbar does not have a chance to show up, nor would it, since it
does not have any buttons. The only problem is that adding/removing
control forces the for to repaint once , but I suspect it can be
overcome by doing this on a hidden form.

private int ExtractIcon(ImageList il, int index)

{

Capture = true;

IntPtr hWnd = GetCapture();

Capture = false;

ToolBar tb = new ToolBar();

tb.ImageList = il;

this.Controls.Add(tb);

IntPtr hWndTB = SHFindMenuBar(hWnd);

IntPtr hIL = SendMessage(hWndTB, TB_GETIMAGELIST, 0, 0);

IntPtr hIcon = ImageList_GetIcon(hIL, index, 0);

IntPtr hDC = GetDC(hWnd);

DrawIconEx(hDC, 20, 20, hIcon, 0, 0, 0, IntPtr.Zero, DI_NORMAL);

ReleaseDC(hWnd, hDC);

hIcon = IntPtr.Zero;

this.Controls.Remove(tb);

}


// P/Invokes
const int WM_USER = 0x400;

const int TB_GETIMAGELIST = WM_USER + 49;

const int DI_NORMAL = 3;

[DllImport("coredll")]

extern static IntPtr GetCapture();

[DllImport("coredll")]

extern static IntPtr ImageList_GetIcon(

IntPtr himl,

int i,

uint flags

);

[DllImport("aygshell")]

extern static IntPtr SHFindMenuBar(IntPtr hwnd);

[DllImport("coredll")]

extern static IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int
lParam);

[DllImport("coredll")]

extern static IntPtr GetDC(IntPtr hWnd);

[DllImport("coredll")]

extern static IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("coredll")]

extern static int DrawIconEx(

IntPtr hDC,

int X,

int Y,

IntPtr hIcon,

int cxWidth,

int cyWidth,

int istepIfAniCur,

IntPtr hbrFlickerFreeDraw,

uint diFlags

);
 
Back
Top