Jump to content


Photo

drag a frame on the screen


  • Please log in to reply
25 replies to this topic

#1 toralf

toralf
  • Fellows
  • 3948 posts

Posted 02 September 2005 - 01:27 PM

Hi all,

I want to drag a frame with the mouse on the screen.
I was wondering if I should use a Gui with transparent inside, or a ToolTip, SplashText or Progress? Or maybe even a transparent GUI covering the whole screen and drawing a control with transparent inside on that GUI?

Does anyone have experience with this?
I have seen freakkk script, he uses a GUI with transparent inside.

Which one is best for performance/handling? I have once done it with a GUI (but with some semi transparent controls on it for "golden cut", etc.) But it had some performance problems: flickering, lag, unstable.

Are ToolTip, SplashText or Progress superior to GUI?

Any other ideas?

#2 BoBo

BoBo
  • Guests

Posted 02 September 2005 - 02:11 PM

Any other ideas?

A HTA with all components disabled,except border. BgColor set within HTA and set transparent via AHK. As its a (Hypertext)application you can use any AHK Window command with it (size, move, hide, ...)

Currently I'm watching video streams that way :wink:

#3 toralf

toralf
  • Fellows
  • 3948 posts

Posted 02 September 2005 - 07:02 PM

Could you please post some sample code? I do not know what HTA is.

#4 BoBo

BoBo
  • Guests

Posted 02 September 2005 - 09:20 PM

[Introduction to HTML Applications (HTAs) ]
[HTML Application: HTA] 8)

MyMTV.HTA
<HTML>
<HEAD>
  <TITLE>MyMTV</TITLE>
  <HTA:APPLICATION ID="oMyMTVApp" 
    APPLICATIONNAME="monster" 
    BORDER="none"
    CAPTION="no"
    ICON="no"
    INNERBORDER="no"
    SHOWINTASKBAR="no"
    SINGLEINSTANCE="yes"
    SYSMENU="no"
    SCROLL="no">
    
    <SCRIPT language="JavaScript">
	<!--
	var NeueBreite = 400;
	var NeueHoehe = 300;
	
	function GroesseVeraendern()
	{
		window.resizeTo(NeueBreite, NeueHoehe);
	}
	//-->
	</SCRIPT>
</HEAD>


<BODY leftmargin="0" topmargin="0" marginheight="0" marginwidth="0" border="0" onLoad="GroesseVeraendern();">
<OBJECT ID="MediaPlayer1" width="400" height="300"
		classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
		codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902"
		standby="Loading Microsoft Windows Media Player components..."
		type="application/x-oleobject">
	<PARAM NAME="FileName" VALUE="http://today.launch.yahoo.com/player/medialog.asp?vid=21900841&bw=56&mf=1&pid=4&ps=0&p1=2&p2=15&p3=2&rpid=35&pv=9&bp=Windows%2520NT&csid=396500550&uid=1516004866&pguid=.lcr_0kb7WovVYuDQFHLdw&etid=0&uguid=36hehil0h22a2&fcv=&z=ms.asx">
	<PARAM NAME="animationatStart" VALUE="true">
	<PARAM NAME="transparentatStart" VALUE="true">
	<PARAM NAME="autoStart" VALUE="true">
	<PARAM NAME="autoClose" VALUE="true">
	<PARAM NAME="showControls" VALUE="false">
	<PARAM NAME="url" VALUE="http://today.launch.yahoo.com/player/medialog.asp?vid=21900841&bw=56&mf=1&pid=4&ps=0&p1=2&p2=15&p3=2&rpid=35&pv=9&bp=Windows%2520NT&csid=396500550&uid=1516004866&pguid=.lcr_0kb7WovVYuDQFHLdw&etid=0&uguid=36hehil0h22a2&fcv=&z=ms.asx">


	<EMBED type="application/x-mplayer2" pluginspage = "http://www.microsoft.com/Windows/MediaPlayer/"
		SRC="http://today.launch.yahoo.com/player/medialog.asp?vid=21900841&bw=56&mf=1&pid=4&ps=0&p1=2&p2=15&p3=2&rpid=35&pv=9&bp=Windows%2520NT&csid=396500550&uid=1516004866&pguid=.lcr_0kb7WovVYuDQFHLdw&etid=0&uguid=36hehil0h22a2&fcv=&z=ms.asx"
		name="MediaPlayer1"
		width=400
		height=300
		AutoStart=true>
	</EMBED>
	</OBJECT>
</BODY>
</HTML>
Above code is set to a connection speed of 56k. To change this to your needs check the code for this string: &bw=56 (3 times)
Optional you can change this to &bw=128 or &bw=300 (recommended). Btw, the video stream needs some secs to load, stay tuned ... :wink:
And yes, this is a sample code which plays only a single video. ---> James Blunt "You're beautiful" (#1 in the UK).
Have fun. :D

#5 BoBo

BoBo
  • Guests

Posted 03 September 2005 - 11:50 AM

As a HTA is able to deal with Java-/VBScript I thought about if its possible to use a centered Imagemap (z.B. eine Tortengrafik, mit transparentem Hintergrund durch WinSet) as an user interface to trigger however, whatever action via onClick, onMouseOver etc.

Run, UserInterface.HTA
If UI1 = 1 ; lets expect the HTA has set an EnvVar value with a mouse click.
Yada yada

Someone can recommend an tiny ImageMap Generator (freeware). Thx. :) ???

#6 not-logged-in-daonlyfreez

not-logged-in-daonlyfreez
  • Guests

Posted 03 September 2005 - 12:32 PM

That's a typical challenge for me :p

This is what I found that looks interesting...

Happy Lad Image Mapper (client-side image maps, 18k)

Tiny, unfortunately a bit buggy, but useable...

Imap 3

Imap 3 is for creating HTML image maps. Features: visually design rectangle, circle and polygon shapes; automatic code generation; integral HTML 3.2 previewer and viewer; integral Text/HTML editor; formats: BMP, GIF, JPEG; re-generate shapes from EXISTING html code (two-way operation!). Help file included. Improved handling and editing of area HREF and ALT.


Image Mapper (free online service)

Also interesting:

Splitz (image slicer/splitter, ~750k)

Splitz! allows you to split any image into rectangular parts and export the resulting images along with the HTML table that puts them back together. This allows webmaster to create for creating mouseover effects and offers an alternative to imagemaps. It supports many images formats and includes smart JPEG compression as well as basic color balancing filters.


iMaker (interface cutter/maker)

iMaker is an image splitting tool. If you have a single large interface image you can use iMaker to split the image up into a usable interface. It even generates the HTML code which should be used to "redraw" the interface in it's complete state.

Current iMaker features include:
Generation of JPEG, PNG or GIF output files
Generation of HTML table to redraw the complete interface
Opens JPG, GIF or BMP interface files
Interface split up can be stored for later reuse
Includes 3 samples



#7 not-logged-in-daonlyfreez

not-logged-in-daonlyfreez
  • Guests

Posted 03 September 2005 - 12:45 PM

The previously mentioned Image Mapper online service has the html-pages used available as a freeware download 8) (apparently works on NN 4.x up and IE 4.x up, it didn't work in Opera)

#8 BoBo

BoBo
  • Guests

Posted 03 September 2005 - 02:59 PM

Tyvm not-logged-in-daonlyfreez :D

Anyone has an idea (JavaScript) which lets a HTML/HTA communicate with its environment/AutoHotkey eg. creates a file, sets an envvar, ... ???

#9 toralf

toralf
  • Fellows
  • 3948 posts

Posted 03 September 2005 - 03:39 PM

Comming back to my topic:

I have again use AHK to do it, since I didn't want to learn another script language.
Currently I have the problem. The frame I drag is a black line with little width. It is not visible on a black backgound. I would like to change the color of the GUI border to yellow. Is there a way?

I tried +Resize to get a big gray frame, but then the Gui has a minimum size of 115 by 24 pixel. Seams that it takes a default titlebar as reference. @Chris: is that by design?

Any other ideas to make the border into a different color or visible on black background?

Here is the code
$Lbutton::
  CoordMode, Mouse ,Screen
  MouseGetPos, MX, MY
  Gui, 1:Color, EEAA99
  Gui, 1:+Lastfound
  WinSet, TransColor, EEAA99
  Gui, 1:-Caption +Border
  ;Gui, 1:+Resize
  Loop
    {
      If GetKeyState("LButton", "P")
        {
          MouseGetPos, MXend, MYend
          w := abs(MX - MXend)
          h := abs(MY - MYend)
          If ( MX < MXend )
              X := MX
          Else
              X := MXend
          If ( MY < MYend )
              Y := MY
          Else
              Y := MYend
          Gui, 1:Show, x%X% y%Y% w%w% h%h%
        }        
      Else
          Break
    }
  MouseGetPos, MXend, MYend
  Gui, 1:Destroy
  ToolTip, %MX% %MY%`n%MXend% %MYend%`n%w% %h%
Return

ESC:: ExitApp

Sorry BoBo, I do not know Java.

#10 not-logged-in-daonlyfreez

not-logged-in-daonlyfreez
  • Guests

Posted 03 September 2005 - 04:02 PM

In all instances you'd need a check-for script running (which might not be what you want)...

- write to cookie and read with AHK
- write to JS message boxes and read with AHK
- write to new 'data' window with JS and read with AHK, which has the advantages that it is a unique updating window, not several message boxes, and that you'll be able to drag it out of sight/hide it.

Starting programs from within a hta/htm is not possible afaik (well, not without necessary modifications/installs).

#11 shimanov

shimanov
  • Guests

Posted 03 September 2005 - 05:32 PM

The following should be self-explanatory:

frame_c = Aqua

frame_w := 100
frame_h := 100
frame_t := 10

frame_x := 100
frame_y := 100

h := frame_h-2*frame_t

Progress, b p1 r0-1 w%frame_w% h%frame_h% x%frame_x% y%frame_y% zh%h% zx%frame_t% zy%frame_t% cbWhite cw%frame_c%,,, Frame Test

WinGet, hw_frame, id, Frame Test

;WinSet, Transcolor, White, ahk_id %hw_frame%

x1 := frame_t
y1 := frame_t
x2 := frame_w-frame_t
y2 := frame_h-frame_t
WinSet, Region, 0-0 %frame_w%-0 %frame_w%-%frame_h% 0-%frame_h% 0-0 %x1%-%y1% %x2%-%y1% %x2%-%y2% %x1%-%y2% %x1%-%y1%, ahk_id %hw_frame%
pause


#12 shimanov

shimanov
  • Guests

Posted 04 September 2005 - 02:22 AM

The code below employs a method, which is likely the most efficient to create a mobile frame. It simply draws a rectangle and avoids the overhead of drawing a solid rectangle then removing some area inside.

For documentation on the various calls, refer to the MSDN Library.

OnExit, handle_exit

update_period	= 100
toggle_period	:= 4*update_period
toggle_time		:= toggle_period

frame_c = 0 
frame_c[0] = 0x808000
frame_c[1] := frame_c[0]^0xFFFFFF

frame_w = 100						; width
frame_h = 100						; height
frame_t = 5							; thickness

; frame
Gui, +AlwaysOnTop -Caption
Gui, Color, Black 
Gui, Show, w%a_ScreenWidth% h%a_ScreenHeight% x0 y0, Frame Test

WinGet, hw_frame, id, Frame Test

WinSet, Transcolor, Black, ahk_id %hw_frame%

hdc_frame := GetDC( hw_frame )

; buffer
hdc_buffer := CreateCompatibleDC( hdc_frame )
hbm_buffer := CreateCompatibleBitmap( hdc_frame, a_ScreenWidth, a_ScreenHeight )
SelectObject( hdc_buffer, hbm_buffer )

h_region := CreateRectRgn( 0, 0, 0, 0 )

SetTimer, timer_MoveFrame, %update_period%
return

handle_exit:
	DrawFrame( 0, 0, 0, 0, 0, 0, true )
	
	DeleteObject( h_region )
	DeleteObject( hbm_buffer )
	
	DeleteDC( hdc_frame )
	DeleteDC( hdc_buffer )
ExitApp

timer_MoveFrame:
	SetBatchLines, -1
	
	CoordMode, mouse, screen

	MouseGetPos, cx, cy
	
	toggle_time -= update_period
	if ( toggle_time = 0 )
	{
		frame_c := !frame_c
		
		toggle_time := toggle_period
	}	
	
	DrawFrame( cx-frame_w//2, cy-frame_h//2, frame_w, frame_h, frame_t, frame_c[%frame_c%]  )
return

DrawFrame( p_x, p_y, p_w, p_h, p_t, p_c, p_restore=false )
{
	global	hdc_frame, hdc_buffer, h_region
	static	buffer_state, old_x, old_y, old_w, old_h
	
	SRCCOPY	= 0x00CC0020
	
	if ( p_x < 0 )
		p_x = 0
	if ( p_y < 0 )
		p_y = 0
		
	t_x := a_ScreenWidth-p_w
	if ( p_x > t_x )
		p_x := t_x
		
	t_y := a_ScreenHeight-p_h
	if ( p_y > t_y )
		p_y := t_y
	
	if ( buffer_state = "full" )
	{
		DllCall( "gdi32.dll\BitBlt", "uint", hdc_frame, "int", old_x, "int", old_y, "int", old_w, "int", old_h, "uint", hdc_buffer, "int", 0, "int", 0, "uint", SRCCOPY )
		
		if ( p_restore )
			return
	}
	else
		buffer_state = full
		
	old_x := p_x
	old_y := p_y
	old_w := p_w
	old_h := p_h

	DllCall( "gdi32.dll\BitBlt", "uint", hdc_buffer, "int", 0, "int", 0, "int", p_w, "int", p_h, "uint", hdc_frame, "int", p_x, "int", p_y, "uint", SRCCOPY )

	DllCall( "gdi32.dll\SetRectRgn", "uint", h_region, "int", p_x, "int", p_y, "int", p_x+p_w, "int", p_y+p_h )

	h_brush := DllCall( "gdi32.dll\CreateSolidBrush", "uint", p_c )

	DllCall( "gdi32.dll\FrameRgn", "uint", hdc_frame, "uint", h_region, "uint", h_brush, "int", p_t, "int", p_t )

	DeleteObject( h_brush )
}

CreateCompatibleDC( p_dc )
{
	return, DllCall( "gdi32.dll\CreateCompatibleDC", "uint", p_dc )
}

DeleteDC( p_dc )
{
	DllCall( "gdi32.dll\DeleteDC", "uint", p_dc )
}

GetDC( p_hw )
{
	return, DllCall( "GetDC", "uint", p_hw )
}

DeleteObject( p_object )
{
	DllCall( "gdi32.dll\DeleteObject", "uint", p_object )
}

SelectObject( p_dc, p_bitmap )
{
	DllCall( "gdi32.dll\SelectObject", "uint", p_dc, "uint", p_bitmap )
}

CreateCompatibleBitmap( p_dc, p_w, p_h )
{
	return, DllCall( "gdi32.dll\CreateCompatibleBitmap", "uint", p_dc, "int", p_w, "int", p_h )
}

CreateRectRgn( p_x1, p_y1, p_x2, p_y2 )
{
	return, DllCall( "gdi32.dll\CreateRectRgn", "int", p_x1, "int", p_y1, "int", p_x2, "int", p_y2 )
}


#13 BoBo

BoBo
  • Guests

Posted 04 September 2005 - 10:05 AM

:shock: Impressing. Please copy that code to the Script section (if not done already). Thx, for sharing it. :D

#14 Chris

Chris
  • Administrators
  • 10727 posts

Posted 04 September 2005 - 12:07 PM

The code below employs a method, which is likely the most efficient to create a mobile frame.

Cool script. I think this is the most elaborate example of DllCall I've seen posted. It's also a great example of how to bend Gdi32.dll to your will, and I'll be learning from it.

I tried +Resize to get a big gray frame, but then the Gui has a minimum size of 115 by 24 pixel.

I believe that is the default set by the OS when a window has certain styles (apparently WS_SIZEBOX is one of them).

In light of shimanov's impressive demonstration above, you might no longer need an answer for this. But if you do, you can do it with OnMessage():
OnMessage(0x24, "WM_GETMINMAXINFO")
$Lbutton::
...
WM_GETMINMAXINFO(wParam, lParam)
{
	if not A_Gui  ; No GUI window number, so it's not for a GUI window: do nothing.
		return
	; Alter the MINMAXINFO structure's ptMinTrackSize X and Y (8 bytes):
	InsertIntegerAtAddress(0, lParam, 24, 8)  
	return 0  ; MSDN: "If an application processes this message, it should return zero."
}

InsertIntegerAtAddress(pInteger, pAddress, pOffset = 0, pSize = 4)
{
	mask := 0xFF  ; This serves to isolate each byte, one by one.
	Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
	{
		DllCall("RtlFillMemory", UInt, pAddress + pOffset + A_Index - 1, UInt, 1  ; Write one byte.
			, UChar, (pInteger & mask) >> 8 * (A_Index - 1))  ; This line is auto-merged with above at load-time.
		mask := mask << 8  ; Set it up for isolation of the next byte.
	}
}


#15 shimanov

shimanov
  • Guests

Posted 04 September 2005 - 05:37 PM

Cool script. I think this is the most elaborate example of DllCall I've seen posted. It's also a great example of how to bend Gdi32.dll to your will, and I'll be learning from it.


Thanks. With AHk it was a straightforward task to implement, once the initial research was complete. The challenge was to identify a method, which would overcome performance limitations. For that, it was necessary to access the Windows API. For those not familiar with Microsoft's developer resources, review the following:

MSDN (Microsoft Developer Network) - the authoritative Windows development resource

Windows 2000/XP/etc. SDK (Software Development Kit) - includes documentation, header files, and more. this is where you will find the API documented, as well as, the codes for SendMessage/PostMessage, DllCall, etc.

Combine Microsoft's resources with AHk and your creativity, and you have an enjoyable development experience.