开发者

Compliant loading of small OEM icon with LoadImage

开发者 https://www.devze.com 2023-03-18 05:31 出处:网络
I believe what my code complies to LoadImage specification, but despite of explicitly specified dimensions, loaded image is largest non-PNG icon.

I believe what my code complies to LoadImage specification, but despite of explicitly specified dimensions, loaded image is largest non-PNG icon.

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Picture.Icon.Handle := LoadImage(
    0,
    MakeIntResource(OIC_SHIELD),
    IMAGE_ICON,
    GetSystemMetrics(SM_CXSMICON),
    GetSystemMetrics(SM_CYSMICON),
    LR_SHARED
  );
  Win32Check(Image1.Picture.Icon.HandleAllocated);

  OutputDebug开发者_StackOverflowString(PChar(Format('%d×%d', [
    Image1.Picture.Icon.Width, 
    Image1.Picture.Icon.Height
  ]))); //  128×128
end;

Note: i prefer to be compliant to newer LoadImage semantics rather than to rely on the explicit module and resource id (essentially falling back to LoadIcon semantics) as specified in the answer to this question.


Quotes from LoadImage specs are exactly outlining my problem with mutually exclusive LoadImage behaviours (either fail or use previously loaded stock resource, ignoring desired dimensions) - see Adrian McCarthy's answer.


While OIC_SHIELD is Windows 6.0+ specific, the same happens with other stock icons (OIC_xxx constants) present in Windows since version 4.0.


Use SHGetStockIconInfo on Vista and up, and the solution from the other question for all other operating systems.


From the notes on LR_SHARED in the LoadImage documentation that you linked to:

This function finds the first image in the cache with the requested resource name, regardless of the size requested.

Unfortunately, you can't just drop the LR_SHARED because:

When loading a system icon or cursor, you must use LR_SHARED or the function will fail to load the resource.

So that explains the problem, but it's not clear what to do about it. You could use SHGetStockIconInfo. That requires Vista+, but since you're trying to get the shield icon, I assume you're already limited to Vista+.

I'm not a .NET programmer, but it looks like there's an API to get the shield icon.

0

精彩评论

暂无评论...
验证码 换一张
取 消