That doesn't work since GdipCreateHICONFromBitmap requires Bitmap to be a GDI+ Bitmap and not a HBITMAP.
However, I managed to get this working by using the code in
matty's reply to [REQ/HELP] Display Picture as Window Icon. The only real thing that needed changing was that the hIcon had to be read from the DataBloc before being passed to WM_SETICON or DestroyIcon since those normal Win32 functions use the handle as a regular DWORD. Oh, and of course you made some typos.
js code:
var objChatWnds = {};
// Let's not forget the already opened chats
function OnEvent_Initialize(MessengerStart) {
if(Messenger.MyStatus > 0) {
for( var oChatWnd = new Enumerator ( Messenger.CurrentChats ); !oChatWnd.atEnd ( ); oChatWnd.moveNext ( ) ) {
OnEvent_ChatWndCreated( oChatWnd.item() );
}
}
}
// Destroy our generated icons on shutdown
function OnEvent_Uninitialize() {
for( var hChatWnd in objChatWnds ) {
Interop.Call ( 'user32' , 'DestroyIcon' , objChatWnds [ oChatWnd.Handle ] );
delete objChatWnds [ oChatWnd.Handle ];
}
}
// Main function
function setDpAsIcon ( sDpLocation , oChatWnd ) {
var GdipToken = Interop.Allocate ( 4 );
var GdipStartupInput = Interop.Allocate ( 16 );
GdipStartupInput.WriteDWORD( 0 , 1 );
// Initialize GDI+
var bInitialized = Interop.Call( 'gdiplus' , 'GdiplusStartup' , GdipToken , GdipStartupInput , 0 ) === 0;
if ( bInitialized === true ) {
// Load a GDI+ Image from the file
var nImgPtr = Interop.Allocate ( 4 );
Interop.Call( 'gdiplus' , 'GdipLoadImageFromFile' , sDpLocation , nImgPtr );
var hImage = nImgPtr.ReadDWORD ( 0 ) !== 0 ? nImgPtr.ReadDWORD ( 0 ) : false;
if ( hImage !== false ) {
// Get a HICON from the GDI+ Bitmap
var hIcon = Interop.Allocate ( 4 );
Interop.Call ( 'gdiplus' , 'GdipCreateHICONFromBitmap' , hImage , hIcon );
// Read the actual handle and save it
>>> hIcon = hIcon.ReadDWORD ( 0 );<<<
objChatWnds [ oChatWnd.Handle ] = hIcon;
// Set the chat window icon
Interop.Call( 'user32' , 'SendMessageW' , oChatWnd.Handle , 0x80 /* WM_SETICON */ , 0 /* ICON_SMALL */ , hIcon );
Interop.Call( 'user32' , 'SendMessageW' , oChatWnd.Handle , 0x80 /* WM_SETICON */ , 1 /* ICON_BIG */ , hIcon );
}
}
// Shutdown GDI+
Interop.Call( 'gdiplus' , 'GdiplusShutdown' , GdipToken.ReadDWORD ( 0 ) );
}
// Set the icon on new chat windows
function OnEvent_ChatWndCreated ( oChatWnd ) {
if ( oChatWnd.Contacts.Count === 1 ) {
var oContact = new Enumerator ( oChatWnd.Contacts ).item();
setDpAsIcon ( oContact.DisplayPicture , oChatWnd );
}
}
// Remove the icon when a chat window is closed
function OnEvent_ChatWndDestroyed ( oChatWnd ) {
if ( typeof objChatWnds [ oChatWnd.Handle ] === 'object' ) {
Interop.Call( 'user32' , 'SendMessageW' , oChatWnd.Handle , 0x80 /* WM_SETICON */ , 0 /* ICON_SMALL */ , 0 );
Interop.Call( 'user32' , 'SendMessageW' , oChatWnd.Handle , 0x80 /* WM_SETICON */ , 1 /* ICON_SMALL */ , 0 );
Interop.Call ( 'user32' , 'DestroyIcon' , objChatWnds [ oChatWnd.Handle ] );
delete objChatWnds [ oChatWnd.Handle ];
}
}}
Just one small note: when tabbed chats are enabled, the big icon won't show up, but the small ones will still work in the title bar.
Enjoy!
quote:
Originally posted by NoWhereMan
EDIT: I think the problem is that function requires a Bitmap struct as input :/
Luckily, it doesn't.
So my guess would be that the Image class resulted from the loaded file will already be a Bitmap instance, it simply decides which derived class to use based on the type of the loaded file.
quote:
Originally posted by matty
Typos?
Yes, like
oChatWd where you want
oChatWnd and
typeof o === 'object ' where you want
typeof o === 'object'.
(note the loss of the space between object and ' )
But I'll forgive you because you couldn't test it.