1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/icon_loader.h" 6 7 #include <windows.h> 8 #include <shellapi.h> 9 10 #include "base/bind.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/threading/thread.h" 13 #include "third_party/skia/include/core/SkBitmap.h" 14 #include "ui/gfx/icon_util.h" 15 #include "ui/gfx/image/image_skia.h" 16 #include "ui/gfx/size.h" 17 #include "ui/gfx/win/dpi.h" 18 19 // static ReadGroupIDFromFilepath(const base::FilePath & filepath)20IconGroupID IconLoader::ReadGroupIDFromFilepath( 21 const base::FilePath& filepath) { 22 if (!IsIconMutableFromFilepath(filepath)) 23 return filepath.Extension(); 24 return filepath.value(); 25 } 26 27 // static IsIconMutableFromFilepath(const base::FilePath & filepath)28bool IconLoader::IsIconMutableFromFilepath(const base::FilePath& filepath) { 29 return filepath.MatchesExtension(L".exe") || 30 filepath.MatchesExtension(L".dll") || 31 filepath.MatchesExtension(L".ico"); 32 } 33 34 // static ReadIconThreadID()35content::BrowserThread::ID IconLoader::ReadIconThreadID() { 36 return content::BrowserThread::FILE; 37 } 38 ReadIcon()39void IconLoader::ReadIcon() { 40 int size = 0; 41 switch (icon_size_) { 42 case IconLoader::SMALL: 43 size = SHGFI_SMALLICON; 44 break; 45 case IconLoader::NORMAL: 46 size = 0; 47 break; 48 case IconLoader::LARGE: 49 size = SHGFI_LARGEICON; 50 break; 51 default: 52 NOTREACHED(); 53 } 54 55 image_.reset(); 56 57 SHFILEINFO file_info = { 0 }; 58 if (SHGetFileInfo(group_.c_str(), FILE_ATTRIBUTE_NORMAL, &file_info, 59 sizeof(SHFILEINFO), 60 SHGFI_ICON | size | SHGFI_USEFILEATTRIBUTES)) { 61 scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON( 62 file_info.hIcon)); 63 if (bitmap.get()) { 64 gfx::ImageSkia image_skia(gfx::ImageSkiaRep( 65 *bitmap, gfx::win::GetDeviceScaleFactor())); 66 image_skia.MakeThreadSafe(); 67 image_.reset(new gfx::Image(image_skia)); 68 DestroyIcon(file_info.hIcon); 69 } 70 } 71 72 // Always notify the delegate, regardless of success. 73 target_message_loop_->PostTask(FROM_HERE, 74 base::Bind(&IconLoader::NotifyDelegate, this)); 75 } 76