PDA

View Full Version : UI_ Pixels, Units & all that



ReneMiner
19-10-2013, 23:48
I have some problem concerning getting correct mouseposition inside canvas.

Canvas supposed to have Pixels, Mouse probably also has Pixels... in the end I'm only interested to have in Mouse.X and Mouse.Y the correct coordinates in relation to canvas.

Problem is: I can not use Dialog New Pixels on create because then the controls and the dialog are different sized than in Resed designed. But I need the exact mouse-position inside canvas in Pixels...

Here is some script I created using my rc-translator. (I shortened a little) - keep eyes on the callback-function


Problem is it does not give me correct X and Y - my head is smoking already - what can I do?
I tried lot of different ways already and now I'm at some point where fun begins to end... :suicide:



'[] Top of script

Uses "UI"

' code created from .rc-file
' C:\Users\René\Downloads\RCIMPORT\someTest.rc
' 2013-10-19 21:26:10



'[] ControlIDs

Begin ControlID
%ID_CANVAS
%IDC_EDT1
End ControlID

Type t_Mouse
X As Long
Y As Long
LButton As Long
MButton As Long
RButton As Long
Wheel As Long
' isOver As DWord ' only needed for multiple dialog apps
End Type

Dim Mouse As t_Mouse

Boolean keepRunning = TRUE

DWord IDD_DLG1


' - - - - - - - - - - - - - - - - - - - -

Function IDD_DLG1_StartUp(ByVal hParent As DWord) As DWord

DWord hDlg, hFont


hDlg = Dialog New hParent,
"Try to resize dialog...",
10,10,330,260,
%WS_VISIBLE | %WS_OVERLAPPEDWINDOW

hFont = Font_Create("MS Sans Serif", 12)
Dialog Send hDlg, %WM_SETFONT, hFont, 0


Control Add Canvas hDlg, %ID_CANVAS, "", 60, 70, 198, 180

Control Set Resize hDlg, %ID_CANVAS, 1, 1, 1, 1

Control Add "Edit", hDlg, %IDC_EDT1, "", 18, 9, 273, 48, %WS_CHILD | %WS_VISIBLE | %WS_TABSTOP | %ES_MULTILINE, %WS_EX_CLIENTEDGE

Function = hDlg

End Function


'[] Callbacks

' - - - - - - - - - - - - - - - - - - - -

CallBack Function IDD_DLG1_Callback()

' ##############################

Static canvasX, canvasY As Long
Static canvasW, canvasH As Long

' ##############################

Select Case CBMSG
Case %WM_INITDIALOG
' -- Put code to be executed after dialog creation here

Canvas_Attach(CBHNDL, %ID_Canvas, %FALSE)

Canvas_Clear(Rgb(0,0,0))
Canvas_Scale Pixels

Canvas_Redraw

' initial memorize canvas x,y,w & h

Control Get Loc CBHNDL, %ID_Canvas To canvasX, canvasY
Control Get Size CBHNDL, %ID_Canvas To canvasW, canvasH
Dialog Units CBHNDL, canvasW, canvasH To Pixels canvasW, canvasH


Case %WM_SIZE, %WM_SIZING
' -- react on resize here
' if form resizes need to check canvas if used Control Set Resize on startup
Control Get Loc CBHNDL, %ID_Canvas To canvasX, canvasY
Control Get Size CBHNDL, %ID_Canvas To canvasW, canvasH
Dialog Units CBHNDL, canvasW, canvasH To Pixels canvasW, canvasH


Case %WM_MOUSEWHEEL
Mouse.Wheel = Sgn(HI(Integer, CBWPARAM))

Case %WM_LBUTTONDOWN
Mouse.LButton = 1

Case %WM_LBUTTONUP
Mouse.LButton = -1

Case %WM_MBUTTONDOWN
Mouse.MButton = 1

Case %WM_MBUTTONUP
Mouse.MButton = -1

Case %WM_RBUTTONDOWN
Mouse.RButton = 1

Case %WM_RBUTTONUP
Mouse.RButton = -1

Case %WM_MOUSEMOVE
Mouse.X = LO(Integer, CBLPARAM)
Mouse.Y = HI(Integer, CBLPARAM)

Dialog Pixels CBHNDL, Mouse.X, Mouse.Y To Units Mouse.X, Mouse.Y

Mouse.X -= canvasX
Mouse.Y -= canvasY

Dialog Units CBHNDL, Mouse.X, Mouse.Y To Pixels Mouse.X, Mouse.Y

Mouse.LButton = IIf((CBWPARAM And %MK_LBUTTON), 2, 0)
Mouse.MButton = IIf((CBWPARAM And %MK_MBUTTON), 2, 0)
Mouse.RButton = IIf((CBWPARAM And %MK_RBUTTON), 2, 0)

String sOut = "Mouse.X = " + Mouse.X + $CRLF
sOut += "Mouse.Y = " + Mouse.Y + $CRLF

If All (_
Between( Mouse.X, 0, CanvasW-1), _
Between( Mouse.Y, 0, CanvasH-1) _
) Then
sOut += "INSIDE CANVAS"
Else
sOut += "OUTSIDE CANVAS"
EndIf

Control Set Text CBHNDL, %IDC_EDT1, sOut
Control Redraw CBHNDL, %IDC_EDT1

Case %WM_CLOSE
' -- Put code to be executed before dialog end here
keepRunning = FALSE
End Select

End Function

' --------------------------------------------------

Function TBKeyboard() As Long

Static vk(255) As Byte
Static i As Long

For i = 1 To 255
If GetAsyncKeyState(i) Then

Select Case i
Case %VK_SHIFT, %VK_LSHIFT, %VK_RSHIFT, %VK_MENU, %VK_LMENU, %VK_RMENU, %VK_CONTROL, %VK_LCONTROL, %VK_RCONTROL
Nop

Case Else
If vk(i) = 0 Then Function = i

End Select

vk(i) = 1
Else
vk(i) = 0
EndIf
Next

End Function



' --------------------------------------------------
Function TBMain()

Long numberOfDialogsAlive


IDD_DLG1 = IDD_DLG1_StartUp(%HWND_DESKTOP)
Dialog Show Modeless IDD_DLG1 Call IDD_DLG1_Callback


While keepRunning
Dialog DoEvents To NumberOfDialogsAlive

Select Case TBKeyboard

Case %VK_ESCAPE
keepRunning = FALSE


End Select


Wend


End Function
'[] End of script


Please make me smile :unguee:

ErosOlmi
19-10-2013, 23:58
UNIT/PIXEL can be a nightmare.
So, just use PIXELS everywhere when you need PIXEL position.

PIXEL syntax in your dialog and change all the rest of the position into pixels

Dialog New Pixels ....

ReneMiner
20-10-2013, 00:04
but this is the problem- I can not use Dialog New Pixels nor Dialog New Units nor Dialog New Name because the sizes of the created controls & dialogs differ from the sizes in the .rc-file then. Everything is about 30% smaller then. But I need pixels in canvas and the exact 0-position (top-left) and exact pixels within canvas to draw at the correct position using the mouse. But however I do it- either X is 10 to high and Y 10 to small or the bottom-right is wrong. So says wrongly inside/outside canvas... and the only logical appearing cause - if I had made no mistake in my code - could be the Dialog Pixels X,Y To Units X,Y works not right because of long integer usage in the calculation.

ErosOlmi
20-10-2013, 10:39
Rene,

I was getting crazy like you but later some tests I discovered that there was I bug in DIALOG PIXELS ... TO UNITS ...

So just invert X with Y in expression after TO UNITS

Dialog Pixels CBHNDL, Mouse.X, Mouse.Y To Units Mouse.y, Mouse.x


Sorry about that.
I will fix for the next release.
Eros

ReneMiner
20-10-2013, 11:44
Thanks- now we've become both crazy :D

I already thought my only way out of this situation would be to write some dialog-designer in tB myself instead of converting the with resed created rc-files to tB.

But how comes none ever found this bug before? Did nobody ever need this function yet - or did they all give up on using UI? Sometimes I think users are just too lazy to post about a bug or weird behaviour so it could get fixed. Instead they complain alike "It's buggy!" - better would be if they try to help by posting about the problem...

So another one: Now I Have to exchange X and Y - but later it will be fixed, so I have to change it back. That bring me to some thought I have to edit all my scripts using this function. How about some tB-Version-Conditionals ?


'assume some built in udt

Type t_TBVersion
Major As Long
Minor As Long
Build As Long
Revision As Long

IsHigher As Function
IsLower As Function
End Type

Global TBVersion as t_TBVersion

' above stuff incl. functions built-in to core....


so I could write alike this:



If TBVersion.IsHigher("1.9.9.0") Then
Dialog Pixels CBHNDL, Mouse.X, Mouse.Y To Units Mouse.X, Mouse.Y
Else
Dialog Pixels CBHNDL, Mouse.X, Mouse.Y To Units Mouse.Y, Mouse.X
Endif

ErosOlmi
20-10-2013, 11:57
By today I will release the quick fix 1.9.10

ReneMiner
20-10-2013, 12:35
just another small question: how comes


Control Set Resize hDlg, %ID_CANVAS, 1, 1, 1, 1

(script at first post, line 53)

has no effect on canvas (it works if I replace canvas with a label) - do I have to detach canvas while %WM_Sizing? And re-attach thereafter?

ErosOlmi
20-10-2013, 12:40
Canvas is a special control, cannot be resized in that way.
But I will have a look in next/next version :)