 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Dennis Jones Guest
|
Posted: Mon Feb 27, 2006 10:03 pm Post subject: Persitent form size/position |
|
|
Hello,
I've been using an old RxLib component (TFormStorage) to remember the size
and position of windows in my app for quite a long time. It has always
seemed to work well. However, I've just become aware of an issue in which it
fails to restore a maximized window properly. That is, if a window is
maximized when it is closed, the next time I open it, it should open
maximzed, but it doesn't.
Since JVCL took over the code for RxLib, I decided to try the JvFormStorage
component, but it fails in exactly the same way (form is positioned in the
upper left corner in the maximized state, but the window does not fill the
screen -- it's left at its normal size).
Interestingly, if the form is the application's main form, it works fine
(both TFormStorage and JvFormStorage). So, I am abandoning the use of
TFormStorage and JvFormStorage (at least for remembering window state). As
a result, I need to find out how to properly restore window state so that I
can get the window to open maximized. What is the proper programtic
procedure for maximizing a window upon opening it? I've tried a couple of
things, but nothing seems to work very well at all.
The only thing that seems to work (at least with respect to giving me a
truly maximized window) is to normalize the window and then immediately
maximize it. Unfortunately, this results in the user seeing the "flying
window" effect (even it LockWindowUpdate is used on the desktop!!), and
leaves odd traces of partial windows/borders on other windows on the
desktop.
I'd appreciate any suggestions.
- Dennis |
|
| Back to top |
|
 |
Randy Guest
|
Posted: Tue Feb 28, 2006 2:03 pm Post subject: Re: Persitent form size/position |
|
|
Dennis Jones wrote:
| Quote: | The only thing that seems to work (at least with respect to giving me a
truly maximized window) is to normalize the window and then immediately
maximize it. Unfortunately, this results in the user seeing the "flying
window" effect (even it LockWindowUpdate is used on the desktop!!), and
leaves odd traces of partial windows/borders on other windows on the
desktop.
|
Here's how I do it in an MDI application (frmMain is the :
// Inhibit the client area from repainting until this operation has
// finished rearranging windows
SNDMSG(frmMain->ClientHandle, WM_SETREDRAW, false, 0);
try
{
// Open a form
TfrmDisplay *fpDisp;
fpDisp = new TfrmDisplay( this );
// Set the window state
if( fpDisp )
{
fpDisp->WindowState = wsMaximized;
}
}
__finally
{
// Put frmMain client area back in normal painting mode and
redraw the
// window
SNDMSG(ClientHandle, WM_SETREDRAW, true, 0);
RedrawWindow( ClientHandle, NULL, NULL,
RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
} |
|
| Back to top |
|
 |
JD Guest
|
Posted: Tue Feb 28, 2006 4:03 pm Post subject: Re: Persitent form size/position |
|
|
"Dennis Jones" <nospam (AT) nospam (DOT) com> wrote:
| Quote: |
[...] but it fails in exactly the same way [...]
I'd appreciate any suggestions.
|
Try mine instead:
//-------------------------------------------------------------
#ifndef FormKeyH
#define FormKeyH
//-------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <Registry.hpp>
#include <memory>
//-------------------------------------------------------------
class PACKAGE TFormKey : public TControl
{
private:
FARPROC FOldWndProc;
FARPROC FNewWndProc;
int FState;
TRect FCoords;
TForm* FForm;
AnsiString RegistryKey;
AnsiString FCompanyName;
AnsiString FApplicationName;
AnsiString FCoordsName;
AnsiString FStateName;
protected:
void __fastcall WndProc( TMessage &Message );
public:
void __fastcall SaveCoordinates();
void __fastcall LoadCoordinates();
__fastcall TFormKey(TComponent* Owner);
__fastcall TFormKey::~TFormKey();
__published:
__property AnsiString CompanyName = { read = FCompanyName, write = FCompanyName };
__property AnsiString ApplicationName = { read = FApplicationName, write = FApplicationName };
};
//-------------------------------------------------------------
#endif
//-------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "FormKey.h"
#pragma package(smart_init)
//-------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TFormKey *)
{
new TFormKey(NULL);
}
//-------------------------------------------------------------
__fastcall TFormKey::TFormKey(TComponent* Owner) : TControl(Owner)
{
FForm = dynamic_cast<TForm*>( Owner );
if( !FForm )
{
throw Exception("TFormKey : Owner is not a TForm.");
}
if( !ComponentState.Contains(csDesigning) )
{
RegistryKey = "Software\\" + FCompanyName + "\\" + FApplicationName;
FStateName = FForm->Name + "_FormState";
FCoordsName = FForm->Name + "_FormCoords";
LoadCoordinates();
FNewWndProc = reinterpret_cast<FARPROC>( MakeObjectInstance(WndProc) );
FOldWndProc = reinterpret_cast<FARPROC>( ::SetWindowLong(FForm->Handle, GWL_WNDPROC, reinterpret_cast<LONG>(FNewWndProc)) );
}
}
//-------------------------------------------------------------
__fastcall TFormKey::~TFormKey()
{
if( !ComponentState.Contains(csDesigning) )
{
SaveCoordinates();
}
}
//-------------------------------------------------------------
void __fastcall TFormKey::LoadCoordinates()
{
bool GotCoords = false, GotState = false;
std::auto_ptr<TRegistry> Registry ( new TRegistry );
try
{
if( Registry->OpenKey(RegistryKey, false) )
{
if( Registry->ValueExists(FCoordsName) )
{
Registry->ReadBinaryData( FCoordsName, &FCoords, sizeof(TRect) );
FForm->Left = FCoords.left;
FForm->Top = FCoords.top;
FForm->Width = FCoords.right;
FForm->Height = FCoords.bottom;
GotCoords = true;
}
if( Registry->ValueExists(FStateName) )
{
Registry->ReadBinaryData( FStateName, &FState, sizeof(int) );
FForm->WindowState = (TWindowState) FState;
GotState = true;
}
}
}
catch( Exception &E )
{
// do nothing
}
if( !GotCoords )
{
FCoords.left = FForm->Left;
FCoords.top = FForm->Top;
FCoords.right = FForm->Width;
FCoords.bottom = FForm->Height;
}
if( !GotState )
{
FState = FForm->WindowState;
}
}
//-------------------------------------------------------------
void __fastcall TFormKey::SaveCoordinates()
{
std::auto_ptr<TRegistry> Registry ( new TRegistry );
try
{
if( Registry->OpenKey(RegistryKey, true) )
{
Registry->WriteBinaryData( FStateName, &FState, sizeof(int) );
Registry->WriteBinaryData( FCoordsName, &FCoords, sizeof(TRect) );
}
}
catch( Exception &E )
{
// do nothing
}
}
//-------------------------------------------------------------
void __fastcall TFormKey::WndProc( TMessage &Message )
{
if( Message.Msg == WM_SYSCOMMAND )
{
switch( Message.WParam )
{
case SC_RESTORE: FState = wsNormal; break;
case SC_MAXIMIZE: FState = wsMaximized; break;
case SC_MINIMIZE: FState = wsMinimized; break;
}
}
else if( Message.Msg == WM_WINDOWPOSCHANGED )
{
if( FState == wsNormal )
{
FCoords.left = FForm->Left;
FCoords.top = FForm->Top;
FCoords.right = FForm->Width;
FCoords.bottom = FForm->Height;
}
}
else if( Message.Msg == WM_DESTROY )
{
::SetWindowLong( FForm->Handle, GWL_WNDPROC, reinterpret_cast<LONG>(FOldWndProc) );
FreeObjectInstance( FNewWndProc );
}
Message.Result = CallWindowProc( FOldWndProc, FForm->Handle, Message.Msg, Message.WParam, Message.LParam );
}
//-------------------------------------------------------------
namespace Formkey
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TFormKey)};
RegisterComponents("Samples", classes, 0);
}
}
//-------------------------------------------------------------
~ JD |
|
| Back to top |
|
 |
Dennis Jones Guest
|
Posted: Tue Feb 28, 2006 5:03 pm Post subject: Re: Persitent form size/position |
|
|
"Randy" <banjolicious (AT) netscape (DOT) net> wrote in message
news:4404517b$1 (AT) newsgroups (DOT) borland.com...
| Quote: | Dennis Jones wrote:
The only thing that seems to work (at least with respect to giving me a
truly maximized window) is to normalize the window and then immediately
maximize it. Unfortunately, this results in the user seeing the "flying
window" effect (even it LockWindowUpdate is used on the desktop!!), and
leaves odd traces of partial windows/borders on other windows on the
desktop.
Here's how I do it in an MDI application (frmMain is the :
|
Okay, that's essentially what I am doing, except that setting the
WindowState at runtime doesn't work for some reason, so I just set the
window size. It's a little less elegant and a little more brute-force, but
it works. Thanks for the reminder of WM_SETREDRAW though...that's cleaner
than using LockWindowUpdate() on the whole desktop.
- Dennis |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|