Page 1 of 2
Save dialog coordinates then redisplay same place
Posted:
Tue Dec 02, 2014 3:43 am
by byron.hopp
I am moving a resource dialog off to the right screen of my two monitors.
My application is running on the left monitor.
I call oDlg:coorsupdate()
Save Top, Left, Right, Bottom to my ini file.
But I haven't figure out how to successfully display the dialog in the same place.
I use
Activate Dialog oDlg on init odlg:move(nTop,nLeft,,,.t.)
Tried using "Redefine ... From .. To" as well.
It doesn't always place back in the same place.
I can play with it, by moving the dialog further to the right than I want, save the coordinates then re-display.
But is there a sure fire way to get it right the first time?
This has a problem even if I keep the dialog on the same screen / monitor.
anybody know where i am failing.
Byron...
Re: Save dialog coordinates then redisplay same place
Posted:
Wed Dec 03, 2014 8:24 pm
by James Bott
Byron,
Well, there are at least three issues.
1) Dialogs do not use pixels, they use dialog units
2) You can't get the pixel location from oDlg:updateCoors()
3) When you are using two different monitors you may have different resolutions to deal with.
You can get the current dialog coordinates (in pixels) using getWndRect(oDlg:hWnd). Then you should be able to use oDlg:move() to restore its location (because Move() uses pixels). This should work for a single monitor, but if you are saving the data on one monitor and restoring it on another, you may have trouble. Also, if you are using CENTERED you may have to compensate for the different resolution.
I suggest starting with a small test program to get it working before trying to integrate it into your program.
James
Re: Save dialog coordinates then redisplay same place
Posted:
Wed Dec 03, 2014 10:39 pm
by James Bott
Byron,
Here is a working example.
James
- Code: Select all Expand view
/*
Purpose : Test showing how to save/restore dialog location
Author : James Bott, jbott@compuserve.com
Date : 12/3/2014 2:09:38 PM
Language: Fivewin/xHarbour
Notes : Drag the dialog to a new position, then close it, then press the button
and the dialog will be restored in the last position.
The location is saved using the VALID clause and restored using oDlg:Move()
The location is saved in memory here, but you could use a file to restore
it.
*/#include "fivewin.ch"static aCoord
Function main
() local oWnd, oBar, oBtn
aCoord :=
{100,
100,
300,
500} define window oWnd
define buttonbar oBar
of oWnd
define button oBtn
of oBar
action MakeDlg
(saveRestore
()) activate window oWnd
maximized on init makeDlg
() return nilFunction MakeDlg
(aRect
) local oDlg
Local nTop,nLeft,nWidth,nHeight
define dialog oDlg
of wndMain
() aRect:= saveRestore
() nTop:= aRect
[1] nLeft:= aRect
[2] nWidth:= aRect
[4] - aRect
[2] nHeight:= aRect
[3] - aRect
[1] activate dialog oDlg
centered ;
VALID ( saveRestore
(getWndRect
(oDlg:
hWnd)), .t.
);
ON INIT oDlg:
move(nTop, nLeft, nWidth
+1, nHeight
+1, .t.
) return nilfunction saveRestore
(aRect
) if aRect !=
nil aCoord := aclone
(aRect
) endifreturn aCoord
// eof
Re: Save dialog coordinates then redisplay same place
Posted:
Wed Dec 03, 2014 11:12 pm
by byron.hopp
James,
Thanks for taking the time to show me this. I haven't heard the term "dialog base units' since the days of Clip4Win.
But you got me working, thanks again.
I did notice that you are adding 1 (one) to the width, and 1 (one) to the height, what's going on there?
Byron ...
Re: Save dialog coordinates then redisplay same place
Posted:
Thu Dec 04, 2014 1:47 am
by James Bott
Byron,
>I did notice that you are adding 1 (one) to the width, and 1 (one) to the height, what's going on there?
I don't know, I found that done elsewhere so I just used it. You could check the saved values against the actuals by making some test code. Or, just leave off the +1 and see what happens. I admit, it does seem odd.
James
Re: Save dialog coordinates then redisplay same place
Posted:
Thu Dec 04, 2014 1:54 am
by James Bott
Byron,
Ok I did some visual testing on the +1 and it is definitely growing. I also tested it without the +1 and it is not shrinking so I would leave off the +1's.
James
Re: Save dialog coordinates then redisplay same place
Posted:
Fri Dec 05, 2014 8:01 am
by Silvio.Falconi
there are two function on ozs Dbu source code run ok and I use from many years
GetWinCoors()
SetWinCoors()
with these function you can move thw window at the same position you closed
It save the coordinates on INI file thinking the state of window( ST_ICONIZED,ST_ZOOMED,ST_NORMAL)
they are very strong.
Re: Save dialog coordinates then redisplay same place
Posted:
Fri Dec 05, 2014 5:31 pm
by byron.hopp
What Mr. Bott posted seems to work perfectly. What you have suggested may be great, but my version of FiveWin can't find the function (the linker can't). Maybe this is only in a later release? If it is in a later release it only reminds that I should upgrade my version.
Thanks,
Byron ...
Re: Save dialog coordinates then redisplay same place
Posted:
Sat Dec 06, 2014 10:42 am
by Silvio.Falconi
Byron,
#define ST_NORMAL 0
#define ST_ICONIZED 1
#define ST_ZOOMED 2
When close the ownd/dialog ->SetWinCoors()
Wnen activate the ownd/dialog call ::GetWinCoors to load position and move the oWnd/odlg in old position
sample :
WITH OBJECT oApp := TApplication():New()
:Activate()
END
METHOD New() CLASS tApplication
DEFINE WINDOW ::oWndMain
....
RETURN Self
METHOD Activate() class TApplication
::GetWinCoors() ::oWndMain:bResized := {|| ResizeWndMain() }
ACTIVATE WINDOW ::oWndMain ;
VALID ::ExitFromX()
::oFont:End()
::oFontMsgItem:End()
return NIL
- Code: Select all Expand view
/*_____________________________________________________________________________*/
/*_____________________________________________________________________________*/
/*___ OZScript ________________________________________________________________*/
METHOD GetWinCoors() CLASS TApplication
LOCAL oIni
LOCAL nRow, nCol, nWidth, nHeight, nState
nRow := VAL(GetPvProfString("Config", "nTop", "10", ::cIniFile))
nCol := VAL(GetPvProfString("Config", "nLeft", "10", ::cIniFile))
nWidth := VAL(GetPvProfString("Config", "nRight", "800", ::cIniFile))
nHeight := VAL(GetPvProfString("Config", "nBottom", "600", ::cIniFile))
nState := VAL(GetPvProfString("Config", "Mode", nState, ::cIniFile))
IF nRow == 0 .AND. nCol == 0
WndCenter(::oWndMain:hWnd)
ELSE
::oWndMain:Move(nRow, nCol, nWidth, nHeight)
ENDIF
IF nState == ST_ICONIZED
::oWndMain:Minimize()
ELSEIF nState == ST_ZOOMED
::oWndMain:Maximize()
ENDIF
UpdateWindow( ::oWndMain:hWnd )
::oWndMain:CoorsUpdate()
SysRefresh()
RETURN NIL
METHOD SetWinCoors() CLASS TApplication
LOCAL oIni
LOCAL nRow, nCol, nWidth, nHeight, nState
::oWndMain:CoorsUpdate()
nRow := ::oWndMain:nTop
nCol := ::oWndMain:nLeft
nWidth := ::oWndMain:nRight-::oWndMain:nLeft
nHeight := ::oWndMain:nBottom-::oWndMain:nTop
IF IsIconic( ::oWndMain:hWnd )
nState := ST_ICONIZED
ELSEIF IsZoomed(::oWndMain:hWnd)
nState := ST_ZOOMED
ELSE
nState := ST_NORMAL
ENDIF
WritePProString("Config","nTop",Ltrim(Str(nrow)),::cIniFile)
WritePProString("Config","nLeft",Ltrim(Str(ncol)),::cIniFile)
WritePProString("Config","nRight",Ltrim(Str(nwidth)),::cIniFile)
WritePProString("Config","nBottom",Ltrim(Str(nheight)),::cIniFile)
WritePProString("Config","Mode",Ltrim(Str(nstate)),::cIniFile)
DbCloseAll()
ResAllFree()
* ::oImgList:End()
RETURN .t.
Re: Save dialog coordinates then redisplay same place
Posted:
Sat Dec 06, 2014 3:54 pm
by byron.hopp
Ok I found SetCoors(), and CoorsUpdate() which contains the Function GetCoors() in it. SetCoors() is a method of the TWindow class. Thank you, I will give them a shot.
James I also discovered this, below is the code to the Method "SetCoors" in the TWindow class:
METHOD SetCoors( oRect ) CLASS TWindow
SetWindowPos( ::hWnd, 0, oRect:nTop, oRect:nLeft,;
oRect:nRight - oRect:nLeft + 1,;
oRect:nBottom - oRect:nTop + 1, 4 ) // Important:
// Use 4 for
::nTop = oRect:nTop // for keeping
::nLeft = oRect:nLeft // ZOrder !!!!
::nBottom = oRect:nBottom
::nRight = oRect:nRight
return nil
This might very well be where you saw the " + 1 " on the coordinates. Someone is doing it here for some reason.
Thanks,
Byron...
Re: Save dialog coordinates then redisplay same place
Posted:
Sat Dec 06, 2014 6:33 pm
by Antonio Linares
The +1 comes from calculating right the total amount.
In example, how many elements are between 5 and 2 ? ( 5, 3, 2 ) Three elements:
5 - 3 = 2 + 1 = 3
Re: Save dialog coordinates then redisplay same place
Posted:
Sun Dec 07, 2014 5:01 am
by James Bott
When I used the +1 in my example the dialog grew by 1 pixel each time it was restored.
Re: Save dialog coordinates then redisplay same place
Posted:
Sun Dec 07, 2014 9:45 pm
by James Bott
Here is an example showing that the coordinates are correct without the +1.
Run the example, move and then close the dialog, then open it again (it will be in the new position), then press the "Get Width/Height" button. The original width and height was 200 and 400, and the new values will be the same.
- Code: Select all Expand view
/*
Purpose : Test showing how to save/restore dialog location
Author : James Bott, jbott@compuserve.com
Date : 12/3/2014 2:09:38 PM
Language: Fivewin/xHarbour
Notes : Drag the dialog to a new position, then close it, then press the button
and the dialog will be restored in the last position.
The location is saved using the VALID clause and restored using oDlg:Move()
The location is saved in memory here, but you could use a file to restore
it.
*/#include "fivewin.ch"static aCoord
Function main
() local oWnd, oBar, oBtn
aCoord :=
{100,
100,
300,
500} define window oWnd
define buttonbar oBar
of oWnd
define button oBtn
of oBar
action MakeDlg
(saveRestore
()) activate window oWnd
maximized on init makeDlg
() return nilFunction MakeDlg
(aRect
) local oDlg
Local nTop,nLeft,nWidth,nHeight
define dialog oDlg
of wndMain
() @
2,
4 BUTTON "Get Width/Height" ;
ACTION ;
msgInfo( cValToChar
(getWndRect
(oDlg:
hWnd)[3]-getWndRect
(oDlg:
hWnd)[1] ) +
"/"+;
cValToChar
(getWndRect
(oDlg:
hWnd)[4]-getWndRect
(oDlg:
hWnd)[2]) ) ;
size 100,
15 activate dialog oDlg
centered ;
VALID ( saveRestore
(getWndRect
(oDlg:
hWnd)), .t.
);
ON INIT oDlg:
move(nTop, nLeft, nWidth, nHeight, .t.
) return nilfunction saveRestore
(aRect
) if aRect !=
nil aCoord := aclone
(aRect
) endifreturn aCoord
// eof
Re: Save dialog coordinates then redisplay same place
Posted:
Sun Dec 07, 2014 10:05 pm
by Antonio Linares
James,
Then it seems as there is a bug somewhere related to this...
What would be the easiest way to reproduce the bug ?
Re: Save dialog coordinates then redisplay same place
Posted:
Sun Dec 07, 2014 11:48 pm
by James Bott
Antonio,
Are you saying there is a bug in the Windows class, or in my example, or elsewhere?
James