no-frills SplashImage Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

no-frills SplashImage

07 Mar 2018, 22:16

I'm trying to write some code to simply display an hBitmap on the screen. I'm trying to do so without using any user-defined functions. The script works, however, there is one flaw mentioned below, if anybody can find a fix for it.

Code: Select all

q:: ;no-frills SplashImage
;note: there is one flaw:
;if the image is smaller than the minimum window size,
;it is stretched
;SysGet, vMinX, 28 ;SM_CXMIN := 28 ;174
;SysGet, vMinY, 29 ;SM_CYMIN := 29 ;38

vDHW := A_DetectHiddenWindows
DetectHiddenWindows, On
vWinTitle := A_ScriptName
vPosX := 300, vPosY := 300
vToggle := !vToggle
if vToggle
	vPosW := 256, vPosH := 256
else
	vPosW := 32, vPosH := 32
hBitmap := LoadPicture(A_AhkPath, "w" vPosW " h" vPosH) ;STM_SETIMAGE will resize the Static control to this width/height

hGuiSplash := DllCall("user32\CreateWindowEx", UInt,vWinExStyle:=0x8, Str,vWinClass:="Static", Str,vWinText:=vWinTitle, UInt,vWinStyle:=0xE, Int,vPosX, Int,vPosY, Int,vPosW, Int,vPosH, Ptr,hWndParent:=0, Ptr,hMenu:=0, Ptr,hInstance:=0, Ptr,vParam:=0, Ptr) ;SS_BITMAP := 0xE ;WS_EX_TOPMOST := 0x8
SendMessage, 0x172, 0, % hBitmap,, % "ahk_id " hGuiSplash ;STM_SETIMAGE := 0x172 ;IMAGE_ICON := 1 ;IMAGE_BITMAP := 0
WinShow, % "ahk_id " hGuiSplash
Sleep, 2000
DllCall("user32\DestroyWindow", Ptr,hGuiSplash)
DetectHiddenWindows, % vDHW
return
Last edited by jeeswg on 08 Mar 2018, 04:49, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: no-frills SplashImage  Topic is solved

07 Mar 2018, 22:31

Perhaps I don't understand, but there is no minimum window size. I have a script that uses a 1x1 window, no caption, and definitively shows as 1x1 when checked. Likewise, I have a screenshot script that allows to make floating images. I've just now tried and got a 15x15 with no distortion. Is it different for Windows 10?

Edit: more specifically, I have the windows with -dpiscale +alwaysOnTop -caption +toolWindow and a picture control. The image is an HBitmap set by the same 0x172 message.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: no-frills SplashImage

07 Mar 2018, 22:40

- Interesting info.
- I use Windows 7. When you run my script, it alternates between 2 sizes, are they both square, or is one of them a distorted rectangle? Thanks.

- [EDIT:] Thanks very much, using WS_EX_TOOLWINDOW := 0x80 has fixed the script, I've corrected it in the script below. I changed vWinExStyle:=0x8 to vWinExStyle:=0x88.

- [EDIT:] I got so fixated trying to change SM_CXMIN/SM_CYMIN, which I haven't found an answer to (yet?). That I didn't think to explore window styles. To change the minimum size for a individual window, involves responding to a SendMessage (WM_GETMINMAXINFO) in the recommended solutions.
- It seems vaguely familiar being able to set a window to *any* size, but I don't specifically recall resizing a window to zero manually, with the mouse.

- While SplashImage has no alternative in AutoHotkey v2, I wanted a short-enough-to-share-on-the-forum script that was two-way compatible, and that didn't use the AHK v1 Gui command (and thus that didn't make the script #Persistent).

- [EDIT:] Btw try resizing Notepad to the minimum size. You essentially get a small amount of the title bar, but you can't make it any smaller.
Last edited by jeeswg on 07 Mar 2018, 23:03, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: no-frills SplashImage

07 Mar 2018, 23:01

Fixed script.

Code: Select all

q:: ;no-frills SplashImage
vDHW := A_DetectHiddenWindows
DetectHiddenWindows, On
vWinTitle := A_ScriptName
vPosX := 300, vPosY := 300
vToggle := !vToggle
if vToggle
	vPosW := 256, vPosH := 256
else
	vPosW := 32, vPosH := 32
hBitmap := LoadPicture(A_AhkPath, "w" vPosW " h" vPosH) ;STM_SETIMAGE will resize the Static control to this width/height

hGuiSplash := DllCall("user32\CreateWindowEx", UInt,vWinExStyle:=0x88, Str,vWinClass:="Static", Str,vWinText:=vWinTitle, UInt,vWinStyle:=0xE, Int,vPosX, Int,vPosY, Int,vPosW, Int,vPosH, Ptr,hWndParent:=0, Ptr,hMenu:=0, Ptr,hInstance:=0, Ptr,vParam:=0, Ptr) ;SS_BITMAP := 0xE ;WS_EX_TOOLWINDOW := 0x80 ;WS_EX_TOPMOST := 0x8
SendMessage, 0x172, 0, % hBitmap,, % "ahk_id " hGuiSplash ;STM_SETIMAGE := 0x172 ;IMAGE_ICON := 1 ;IMAGE_BITMAP := 0
WinShow, % "ahk_id " hGuiSplash
Sleep, 1000
DllCall("user32\DestroyWindow", Ptr,hGuiSplash)
DetectHiddenWindows, % vDHW
return
Last edited by jeeswg on 08 Mar 2018, 04:50, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: no-frills SplashImage

07 Mar 2018, 23:05

Unless LoadPicture() is a built-in v2 function, your above script can't be tested. I use v1.1 and don't have LoadPicture() in my stdlib. It also creates a window that still has a caption, was that on purpose?
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: no-frills SplashImage

07 Mar 2018, 23:33

- Re. LoadPicture:
LoadPicture
https://autohotkey.com/docs/commands/Lo ... icture.htm
[v1.1.23+]
- Re. caption. I wanted the image to display at roughly the correct ratio, that was the only criterion. I'm looking at short scripts for splashing text/images, based on the fact that Progress/SplashImage(/SplashTextXXX) are due to be removed from AutoHotkey v2, and so I wanted replacement functions with basic functionality for diagnostic tests that would work in both AutoHotkey v1 and v2, and that wouldn't cause a script to become #Persistent (which the Gui command does).
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: no-frills SplashImage

07 Mar 2018, 23:44

Oh, interesting. Well in that case, the image just doesn't load for some reason. I'm just getting a plain white window. I'm not terribly understanding of why it matters if the script is persistent or not (I'd prefer it to default persistent), as any hotkey will do that anyway, and I find more consistency in simply using ExitApp. Makes sense to have a replacement ready, though.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: no-frills SplashImage

07 Mar 2018, 23:52

- The issue with #Persistent is this. I have various background scripts that run temporarily, briefly. They use functions from various libraries. If one of those libraries has something in it that causes persistence, then those background scripts won't close unless I rewrite them to force close themselves.
- Every so often it's a cause of dismay when I realise that none of my background scripts have closed, because persistence was somehow invoked.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: no-frills SplashImage

08 Mar 2018, 00:15

No offence, but I'd say you should never rely on a return to do the job of an ExitApp.

Back on-topic, even using a different image, the window shows blank. Why is that? Or was that not working in the first place and you were just getting the dimensions correct?
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: no-frills SplashImage

08 Mar 2018, 04:40

I've fixed both scripts, they needed DetectHiddenWindows, On.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: no-frills SplashImage

08 Mar 2018, 21:03

Now that you've said it, seems really obvious :lol: But I couldn't help myself; I frilled it a little bit. Consider it a fork? Though, it should be cross-compatible still, except for maybe the SplitPath, but that's a supplementary function anyway.

Code: Select all

vPos:={x:300,y:300}

q::
imgpath1:="" ; insert path
imgpath2:="" ; insert path
t:=!t

splashImage(t?imgpath1:imgpath2,getImageSize(t?imgpath1:imgpath2),t?0:vPos,t?100:500)
return

w::
vToggle := !vToggle
if vToggle
    splashImage(a_ahkPath,{width:256,height:256},vPos,,0xffffff)
else
	splashImage(a_ahkPath,{width:32,height:32})
return

splashImage(path,size,pos:="",delay:=1000,trans:=""){ ; size.width and size.height ; pos.x and pos.y
    static hGuiSplash,vDHW
    vDHW := A_DetectHiddenWindows
    DetectHiddenWindows, On
    
    while(hGuiSplash)
        sleep 100
    if(!pos){ ; center coords
        pos:={x:(a_screenWidth//2)-(size.width//2)
            ,y:(a_screenHeight//2)-(size.height//2)}
    }
    hBitmap := LoadPicture(path,"w" . size.width . " h" . size.height) ;STM_SETIMAGE will resize the Static control to this width/height
    hGuiSplash := dllCall("user32\CreateWindowEx", UInt,vWinExStyle:=0x88, Str,vWinClass:="Static", Str,vWinText:=a_scriptName, UInt,vWinStyle:=0xE, Int,pos.x, Int,pos.y, Int,size.width, Int,size.height, Ptr,hWndParent:=0, Ptr,hMenu:=0, Ptr,hInstance:=0, Ptr,vParam:=0, Ptr) ;SS_BITMAP := 0xE ;WS_EX_TOOLWINDOW := 0x80 ;WS_EX_TOPMOST := 0x8
    if(trans)
        winSet,transColor,% trans,% "ahk_id " . hGuiSplash
    winSet,style,-0xC00000,% "ahk_id " . hGuiSplash ; remove caption
    sendMessage,0x172,0,hBitmap,, % "ahk_id " . hGuiSplash ;STM_SETIMAGE := 0x172 ;IMAGE_ICON := 1 ;IMAGE_BITMAP := 0
    winShow, % "ahk_id " . hGuiSplash
    setTimer,splashImage_finish,% delay!="off"?"-" . delay:"off"
    return
    
    splashImage_finish:
    dllCall("user32\DestroyWindow", Ptr,hGuiSplash)
    detectHiddenWindows, % vDHW
    hGuiSplash:=""
    return
}

getImageSize(imagePath){
    splitPath,imagePath,fN,fD

    oS:=comObjCreate("Shell.Application")
    oF:=oS.namespace(fD?fD:a_workingDir)
    oFn:=oF.parseName(fD?fN:imagePath)
    size:=strSplit(oFn.extendedProperty("Dimensions"),"x"
        ," ?" . chr(8234) chr(8236))

    return {width: size[1],height: size[2]}
}
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: no-frills SplashImage

11 Apr 2018, 23:55

tl;dr: drawing image onto window works temporarily, not permanently

- I've been looking at the source code for SplashImage. (The function is called Splash() and is in script2.cpp, with further code in MainWindowProc().) I've created the script below based on it. Like SplashImage, it draws directly onto the GUI and doesn't use a Static control. However, the image disappears if you focus another window. Can this be fixed?
- This drawing technique would be a really useful general technique.
- Also, which uses less memory, drawing onto the GUI, or using a Static control? Thanks.
- [EDIT:] Note: the script as it is is great, you can draw onto Notepad, and then focus away and come back, and the image is gone, thus it's great for drawing temporarily on the screen.
- [EDIT:] I've added a hotkey which can redraw the image.
- [EDIT:] This script produces a permanent image, but unlike SplashImage, the image is not retrieved by certain printscreen techniques.
graphics: kaleidoscope/brush mirrors - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=35597

Code: Select all

q:: ;draw bitmap/icon onto GUI
vToggle := !vToggle
vMgnX := 5, vMgnY := 5
;vImgW := 32, vImgH := 32
vImgW := 256, vImgH := 256
vImgX := vMgnX, vImgY := vMgnY
vWinW := vImgW + 2*vMgnX
vWinH := vImgH + 2*vMgnY

if vToggle
	hBitmap := LoadPicture(A_AhkPath, Format("W{} H{}", vImgW, vImgH)), vImgType := 0
else
	hIcon := LoadPicture(A_AhkPath, Format("W{} H{}", vImgW, vImgH), vImgType)

;WinGet, hWnd, ID, ahk_class Notepad
Gui, New, +HwndhGui
Gui, Show, % Format("W{} H{}", vWinW, vWinH)
hWnd := hGui
;===============
;test code to redraw the image
w::
if InStr(A_ThisHotkey, "w")
{
	WinGet, hWnd, ID, A
	WinGetClass, vWinClass, % "ahk_id " hWnd
	if !(vWinClass = "AutoHotkeyGUI")
		return
}
;===============
hDC1 := DllCall("user32\GetDC", Ptr,hWnd, Ptr)
if (vImgType = 0) ;IMAGE_BITMAP := 0
{
	hDC := DllCall("gdi32\CreateCompatibleDC", Ptr,hDC1, Ptr)
	hBitmapOld := DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hBitmap, Ptr)
	DllCall("gdi32\BitBlt", Ptr,hDC1, Int,vImgX, Int,vImgY, Int,vImgW, Int,vImgH, Ptr,hDC, Int,0, Int,0, UInt,0x00CC0020) ;SRCCOPY := 0x00CC0020
	DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hBitmapOld, Ptr)
	DllCall("gdi32\DeleteDC", Ptr,hDC)
}
else if (vImgType = 1) ;IMAGE_ICON := 1
	DllCall("user32\DrawIconEx", Ptr,hDC1, Int,vMgnX, Int,vMgnX, Ptr,hIcon, Int,vImgW, Int,vImgH, UInt,0, Ptr,0, UInt,0x3) ;DI_NORMAL := 0x3
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: no-frills SplashImage

12 Apr 2018, 22:16

I have a fix, I'll be posting shortly, the script needs to handle WM_ERASEBKGND.
[EDIT:] Here's the fix:

Code: Select all

;WM_ERASEBKGND := 0x14
OnMessage(0x14, "WM_ERASEBKGND")

q:: ;draw bitmap/icon onto GUI
vToggle := !vToggle
vMgnX := 5, vMgnY := 5
;vImgW := 32, vImgH := 32
vImgW := 256, vImgH := 256
vImgX := vMgnX, vImgY := vMgnY
vWinW := vImgW + 2*vMgnX
vWinH := vImgH + 2*vMgnY

if vToggle
	hBitmap := LoadPicture(A_AhkPath, Format("W{} H{}", vImgW, vImgH)), vImgType := 0
else
	hIcon := LoadPicture(A_AhkPath, Format("W{} H{}", vImgW, vImgH), vImgType)

;WinGet, hWnd, ID, ahk_class Notepad
Gui, New, +HwndhGui
Gui, Show, % Format("W{} H{}", vWinW, vWinH)
hWnd := hGui
;===============
;test code to redraw the image
w::
if InStr(A_ThisHotkey, "w")
{
	WinGet, hWnd, ID, A
	WinGetClass, vWinClass, % "ahk_id " hWnd
	if !(vWinClass = "AutoHotkeyGUI")
		return
}
;===============
hDC1 := DllCall("user32\GetDC", Ptr,hWnd, Ptr)
if (vImgType = 0) ;IMAGE_BITMAP := 0
{
	hDC := DllCall("gdi32\CreateCompatibleDC", Ptr,hDC1, Ptr)
	hBitmapOld := DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hBitmap, Ptr)
	DllCall("gdi32\BitBlt", Ptr,hDC1, Int,vImgX, Int,vImgY, Int,vImgW, Int,vImgH, Ptr,hDC, Int,0, Int,0, UInt,0x00CC0020) ;SRCCOPY := 0x00CC0020
	DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hBitmapOld, Ptr)
	DllCall("gdi32\DeleteDC", Ptr,hDC)
}
else if (vImgType = 1) ;IMAGE_ICON := 1
	DllCall("user32\DrawIconEx", Ptr,hDC1, Int,vMgnX, Int,vMgnX, Ptr,hIcon, Int,vImgW, Int,vImgH, UInt,0, Ptr,0, UInt,0x3) ;DI_NORMAL := 0x3
return

WM_ERASEBKGND(wParam, lParam, uMsg, hWnd2)
{
	global
	vDoDrawImg := 1 ;set this to 0 and the image won't be redrawn
	vDoDrawBgd := 1 ;set this to 0 and the background won't be redrawn
	;return ;uncomment this line and the window will be blank

	hWnd := hWnd2
	if !(hWnd = hGui)
		return
	hDC1 := DllCall("user32\GetDC", Ptr,hWnd, Ptr)
	if !vDoDrawImg
		Sleep, 0
	else if (vImgType = 0) ;IMAGE_BITMAP := 0
	{
		hDC := DllCall("gdi32\CreateCompatibleDC", Ptr,hDC1, Ptr)
		hBitmapOld := DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hBitmap, Ptr)
		DllCall("gdi32\BitBlt", Ptr,hDC1, Int,vImgX, Int,vImgY, Int,vImgW, Int,vImgH, Ptr,hDC, Int,0, Int,0, UInt,0x00CC0020) ;SRCCOPY := 0x00CC0020
		DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hBitmapOld, Ptr)
		DllCall("gdi32\DeleteDC", Ptr,hDC)
	}
	else if (vImgType = 1) ;IMAGE_ICON := 1
		DllCall("user32\DrawIconEx", Ptr,hDC1, Int,vMgnX, Int,vMgnX, Ptr,hIcon, Int,vImgW, Int,vImgH, UInt,0, Ptr,0, UInt,0x3) ;DI_NORMAL := 0x3

	if vDoDrawBgd
	{
		hDC2 := wParam
		DllCall("gdi32\ExcludeClipRect", Ptr,hDC2, Int,vImgX, Int,vImgY, Int,vImgX+vImgW, Int,vImgY+vImgH)
		hRgn := DllCall("gdi32\CreateRectRgn", Int,0, Int,0, Int,1, Int,1, Ptr)
		DllCall("gdi32\GetClipRgn", Ptr,hDC2, Ptr,hRgn)
		hBrush := DllCall("user32\GetSysColorBrush", Int,15, Ptr) ;COLOR_BTNFACE := 15
		DllCall("gdi32\FillRgn", Ptr,hDC2, Ptr,hRgn, Ptr,hBrush)
		DllCall("gdi32\DeleteObject", Ptr,hRgn)
	}
	return 1
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Chunjee, Google [Bot] and 114 guests