MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / ControlLoadPicture

Method ControlLoadPicture

source/script_gui.cpp:6958–7072  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6956
6957
6958ResultType GuiType::ControlLoadPicture(GuiControlType &aControl, LPTSTR aFilename, int aWidth, int aHeight, int aIconNumber)
6959{
6960 // LoadPicture() uses CopyImage() to scale the image, which seems to provide better scaling
6961 // quality than using MoveWindow() (followed by redrawing the parent window) on the static
6962 // control that contains the image.
6963 int image_type;
6964 HBITMAP new_image = LoadPicture(aFilename, aWidth, aHeight, image_type, aIconNumber
6965 , aControl.attrib & GUI_CONTROL_ATTRIB_ALTSUBMIT);
6966 if (!new_image && *aFilename)
6967 return FAIL; // Caller will report the error.
6968
6969 // In light of the below, it seems best to delete the bitmaps whenever the control changes
6970 // to a new image or whenever the control is destroyed. Otherwise, if a control or its
6971 // parent window is destroyed and recreated many times, memory allocation would continue
6972 // to grow from all of the abandoned bitmaps/icons.
6973 // MSDN: "When you are finished using a bitmap...loaded without specifying the LR_SHARED flag,
6974 // you can release its associated memory by calling...DeleteObject."
6975 // MSDN: "The system automatically deletes these resources when the process that created them
6976 // terminates, however, calling the appropriate function saves memory and decreases the size
6977 // of the process's working set."
6978 // v1.0.40.12: For maintainability, destroy the handle returned by STM_SETIMAGE, even though it
6979 // should be identical to control.union_hbitmap (due to a call to STM_GETIMAGE in another section).
6980 // UPDATE: This is now done after LoadPicture() is called to reduce the length of time between
6981 // the background being erased and the new picture being drawn, which might decrease flicker.
6982 // It's still done as a separate step to setting the new bitmap due to uncertainty about how
6983 // the control handles changing the image type, and the notes below about animation.
6984 if (aControl.union_hbitmap)
6985 if (aControl.attrib & GUI_CONTROL_ATTRIB_ALTBEHAVIOR) // union_hbitmap is an icon or cursor.
6986 // The control's image is set to NULL for the following reasons:
6987 // 1) It turns off the control's animation timer in case the new image is not animated.
6988 // 2) It feels a little bit safer to destroy the image only after it has been removed
6989 // from the control.
6990 // NOTE: IMAGE_ICON or IMAGE_CURSOR must be passed, not IMAGE_BITMAP. Otherwise the
6991 // animated property of the control (via a timer that the control created) will remain
6992 // in effect for the next image, even if it isn't animated, which results in a
6993 // flashing/redrawing effect:
6994 DestroyIcon((HICON)SendMessage(aControl.hwnd, STM_SETIMAGE, IMAGE_CURSOR, NULL));
6995 // DestroyIcon() works on cursors too. See notes in LoadPicture().
6996 else // union_hbitmap is a bitmap
6997 DeleteObject((HGDIOBJ)SendMessage(aControl.hwnd, STM_SETIMAGE, IMAGE_BITMAP, NULL));
6998 aControl.union_hbitmap = new_image;
6999 if (!new_image)
7000 {
7001 // By design, no error is reported for a blank aFilename.
7002 // For simplicity, any existing SS_BITMAP/SS_ICON style bit is not removed.
7003 return OK;
7004 }
7005 if (image_type == IMAGE_ICON && aControl.background_color == CLR_TRANSPARENT)
7006 {
7007 // Static controls don't appear to support background transparency with icons,
7008 // so convert the icon to a bitmap.
7009 if (HBITMAP hbitmap = IconToBitmap32((HICON)aControl.union_hbitmap, false))
7010 {
7011 DestroyIcon((HICON)aControl.union_hbitmap);
7012 aControl.union_hbitmap = hbitmap;
7013 image_type = IMAGE_BITMAP;
7014 }
7015 }

Callers

nothing calls this directly

Calls 2

LoadPictureFunction · 0.85
IconToBitmap32Function · 0.85

Tested by

no test coverage detected