Save dialog coordinates then redisplay same place

Save dialog coordinates then redisplay same place

Postby byron.hopp » Tue Dec 02, 2014 3:43 am

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...
Thanks,
Byron Hopp
Matrix Computer Services
byron.hopp
 
Posts: 347
Joined: Sun Nov 06, 2005 3:55 pm
Location: Southern California, USA

Re: Save dialog coordinates then redisplay same place

Postby James Bott » Wed Dec 03, 2014 8:24 pm

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
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Save dialog coordinates then redisplay same place

Postby James Bott » Wed Dec 03, 2014 10:39 pm

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 nil

Function 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 nil

function saveRestore(aRect)
   if aRect != nil
      aCoord := aclone(aRect)
   endif
return aCoord

// eof
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Save dialog coordinates then redisplay same place

Postby byron.hopp » Wed Dec 03, 2014 11:12 pm

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 ...
Thanks,
Byron Hopp
Matrix Computer Services
byron.hopp
 
Posts: 347
Joined: Sun Nov 06, 2005 3:55 pm
Location: Southern California, USA

Re: Save dialog coordinates then redisplay same place

Postby James Bott » Thu Dec 04, 2014 1:47 am

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
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Save dialog coordinates then redisplay same place

Postby James Bott » Thu Dec 04, 2014 1:54 am

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
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Save dialog coordinates then redisplay same place

Postby Silvio.Falconi » Fri Dec 05, 2014 8:01 am

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.
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: Save dialog coordinates then redisplay same place

Postby byron.hopp » Fri Dec 05, 2014 5:31 pm

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 ...
Thanks,
Byron Hopp
Matrix Computer Services
byron.hopp
 
Posts: 347
Joined: Sun Nov 06, 2005 3:55 pm
Location: Southern California, USA

Re: Save dialog coordinates then redisplay same place

Postby Silvio.Falconi » Sat Dec 06, 2014 10:42 am

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.
 
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: Save dialog coordinates then redisplay same place

Postby byron.hopp » Sat Dec 06, 2014 3:54 pm

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...
Thanks,
Byron Hopp
Matrix Computer Services
byron.hopp
 
Posts: 347
Joined: Sun Nov 06, 2005 3:55 pm
Location: Southern California, USA

Re: Save dialog coordinates then redisplay same place

Postby Antonio Linares » Sat Dec 06, 2014 6:33 pm

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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41315
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Save dialog coordinates then redisplay same place

Postby James Bott » Sun Dec 07, 2014 5:01 am

When I used the +1 in my example the dialog grew by 1 pixel each time it was restored.
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Save dialog coordinates then redisplay same place

Postby James Bott » Sun Dec 07, 2014 9:45 pm

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 nil

Function 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 nil

function saveRestore(aRect)
   if aRect != nil
      aCoord := aclone(aRect)
   endif
return aCoord

// eof
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Save dialog coordinates then redisplay same place

Postby Antonio Linares » Sun Dec 07, 2014 10:05 pm

James,

Then it seems as there is a bug somewhere related to this...

What would be the easiest way to reproduce the bug ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41315
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Save dialog coordinates then redisplay same place

Postby James Bott » Sun Dec 07, 2014 11:48 pm

Antonio,

Are you saying there is a bug in the Windows class, or in my example, or elsewhere?

James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 83 guests