Showing posts with label ide. Show all posts
Showing posts with label ide. Show all posts
Wednesday, June 2, 2010
User defined color-schemes
As the lazarus community grows people yearn for more customizations to please their personal habits.
To help creating a wider choice of readily available settings, user defined color schemes have been introduced.
So now, your community needs you.
Get the latest Lazarus snapshot, load your favourite color settings (or create the perfect scheme from scratch) and then make it available to all of us. All you need is press "Export", enter a Name and save it.
Upload it to your home page, or a place of your choice and link it on our wiki so everyone will find it.
Wiki page to link to your scheme(s): wiki.lazarus.freepascal.org/UserSuppliedSchemeSettings
Documentation: wiki.lazarus.freepascal.org/IDE_Window:_Editor_Options_HighlightColors
Documentation: wiki.lazarus.freepascal.org/IDE_Window:_Editor_Options_HighlightColors
Sunday, October 28, 2007
How TPageControl tab switching in designer has been solved
I think most users who used TPageControl in windows ide suffered from the inability to stitch its Tabs by clicking them in the designer. Indeed, the gtk ide had no such bug while the windows one had. I got annoyed by the fact too and as result I started my research of the problem.
My first assumption was that somewhere a csDesigning (you know that usual "if csDesigning in BlaBla.ComponentState" ;) ) condition was written and I spent much time (searching code) to prove myself that I am wrong.
Ok, if I am wrong (I thought) then it is by design or by the designer :) So I started my research of how the win32 designer works. Usually my research consists of Alt+F7 in Far manager for some search key (in this case for 'designer') and if Alt+F7 doesn't help, then in debugging the code. I suppose on that occasion I had been satisfied by search in files. First of all I found 'TWin32WidgetSet.GetDesignerDC' method and later I've checked that this method is indeed what I searched for. Look at TDesigner.DrawDesignerItems and you'll find that yourself.
So, I've known the enemy by sight :) If you notice GetDesignerDC creates a visually transparent window over WindowHandle and returns the Device Context for that overlay window. The Device Context is not a interesting thing for us, but the overlay window is. That overlay window is placed on top of a form (and all child controls). And the most interesting thing in that overlay window is the window procedure OverlayWindowProc.
Inside OverlayWindowProc we can find that overlay window easts all messages except WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST and that bunch of messages it redirects to the parent (look at Windows.GetParent(Window)). If you look at TDesigner.DrawDesignerItems then you'll know that the Parent of OverlayWindow is the Form. So nothing wondering now that the PageControl Tabs cannot be switched in designer - PageControl gets no clicks (they are caught by our overlay window).
Hmm ... I thought about a solution. The first thing that flashed through my mind was sending those mouse clicks to the underlying control. But it is so easy to forget about some messages or make other errors if you want to emulate windows behaviour. So I rejected that way as defective. Another way is to make some parts of our overlay window transparent for mouse. Windows has a special message WM_NCHITTEST to check what a given coordinate means. And a window can return HTTRANSPARENT as result of a message to indicate that message must be sent to the underlying window (so this point is transparent for the window).
As result the whole solution consisted of handling WM_NCHITTEST in OverlayWindowProc and return HTTRANSPARENT if underlying control wanted mouse messages for that point at design time. I've added a new method GetDesignInteractive to TWSWinControl.
class function GetDesignInteractive(const AWinControl: TWinControl; AClientPos: TPoint): Boolean;
Now I had a method to check, but of course I needed the implementation of that method for TPageControl (which checked that mouse is over control Tabs). So I've added TWin32WSCustomNotebook.GetDesignInteractive, rebuilt the win32 ide and hurray - I switched PageControl tabs in designer w/o problems.
You can look at implementation in revisions: 12245, 12620 (method has been renamed).
My first assumption was that somewhere a csDesigning (you know that usual "if csDesigning in BlaBla.ComponentState" ;) ) condition was written and I spent much time (searching code) to prove myself that I am wrong.
Ok, if I am wrong (I thought) then it is by design or by the designer :) So I started my research of how the win32 designer works. Usually my research consists of Alt+F7 in Far manager for some search key (in this case for 'designer') and if Alt+F7 doesn't help, then in debugging the code. I suppose on that occasion I had been satisfied by search in files. First of all I found 'TWin32WidgetSet.GetDesignerDC' method and later I've checked that this method is indeed what I searched for. Look at TDesigner.DrawDesignerItems and you'll find that yourself.
So, I've known the enemy by sight :) If you notice GetDesignerDC creates a visually transparent window over WindowHandle and returns the Device Context for that overlay window. The Device Context is not a interesting thing for us, but the overlay window is. That overlay window is placed on top of a form (and all child controls). And the most interesting thing in that overlay window is the window procedure OverlayWindowProc.
Inside OverlayWindowProc we can find that overlay window easts all messages except WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST and that bunch of messages it redirects to the parent (look at Windows.GetParent(Window)). If you look at TDesigner.DrawDesignerItems then you'll know that the Parent of OverlayWindow is the Form. So nothing wondering now that the PageControl Tabs cannot be switched in designer - PageControl gets no clicks (they are caught by our overlay window).
Hmm ... I thought about a solution. The first thing that flashed through my mind was sending those mouse clicks to the underlying control. But it is so easy to forget about some messages or make other errors if you want to emulate windows behaviour. So I rejected that way as defective. Another way is to make some parts of our overlay window transparent for mouse. Windows has a special message WM_NCHITTEST to check what a given coordinate means. And a window can return HTTRANSPARENT as result of a message to indicate that message must be sent to the underlying window (so this point is transparent for the window).
As result the whole solution consisted of handling WM_NCHITTEST in OverlayWindowProc and return HTTRANSPARENT if underlying control wanted mouse messages for that point at design time. I've added a new method GetDesignInteractive to TWSWinControl.
class function GetDesignInteractive(const AWinControl: TWinControl; AClientPos: TPoint): Boolean;
Now I had a method to check, but of course I needed the implementation of that method for TPageControl (which checked that mouse is over control Tabs). So I've added TWin32WSCustomNotebook.GetDesignInteractive, rebuilt the win32 ide and hurray - I switched PageControl tabs in designer w/o problems.
You can look at implementation in revisions: 12245, 12620 (method has been renamed).
Subscribe to:
Posts (Atom)