Origin 0,0 (in)dependent from themes?
-
- Posts: 11
- Joined: Fri Jan 29, 2010 1:37 am
Origin 0,0 (in)dependent from themes?
I have an application where I fully control all the objects on pixel level. I am struggling however with the origin { 0,0 }position when working with different themes. In the attachments you can find code and the output for themes "Windows Classic" and "Windows Vista" of a test program that prints two pushbuttons. My practical experience is that with "non-Classic" themes I have to add about 7-9 pixels to the desired position. I see however no exact relation with the SM_CYCAPTION, SM_CYFRAME and SM_CYBORDER parameters of GetSystemMetrics (DLL).
My questions:
- Where is exactly the origin 0,0 in eXpress++?
- Is this a fixed point, derived from the "Windows Classic" theme?
- What is the formula to find the first "usable" pixel on the Y-axis?
Daan
My questions:
- Where is exactly the origin 0,0 in eXpress++?
- Is this a fixed point, derived from the "Windows Classic" theme?
- What is the formula to find the first "usable" pixel on the Y-axis?
Daan
- Attachments
-
- test1.zip
- (466 Bytes) Downloaded 1065 times
-
- TestOrigin.jpg (62.94 KiB) Viewed 19475 times
Re: Origin 0,0 (in)dependent from themes?
this is DWM (Desktop Windows Manager) "Border Padding"daan_vossebeld wrote:I have an application where I fully control all the objects on pixel level. I am struggling however with the origin { 0,0 }position when working with different themes. In the attachments you can find code and the output for themes "Windows Classic" and "Windows Vista" of a test program that prints two pushbuttons.
try this DWM Code on Vista(?)/Win7
Code: Select all
#include "DLL.CH"
#include "GRA.CH"
#include "XBP.CH"
DLLFUNCTION DwmExtendFrameIntoClientArea( nHWND, pMargins ) ;
USING STDCALL ;
FROM DWMAPI.DLL
DLLFUNCTION DwmIsCompositionEnabled( @nEnabled ) ;
USING STDCALL ;
FROM DWMAPI.DLL
#define cxLeftWidth 0
#define cxRightWidth 4
#define cyTopHeight 8
#define cyBottomHeight 12
PROCEDURE Main()
LOCAL oDlg
LOCAL oTxt
oDlg := VistaDialog():New( AppDesktop() )
oDlg:Title := "Vista Dialog with Glass"
oDlg:TaskList := .T.
oDlg:PadLeft := 5
oDlg:PadRight := 5
oDlg:PadTop := 5
oDlg:PadBottom := 45
oDlg:Visible := .F.
oDlg:Create( ,,, {400,200} )
oTxt := XbpSLE():New( oDlg )
oTxt:Create( ,, {10,5},{150,25} )
oTxt:SetData( "Test Frame..." )
CenterControl( oDlg )
oDlg:ShowModal()
oDlg:Destroy()
RETURN
CLASS VistaDialog FROM XbpDialog
EXPORTED:
VAR PadLeft
VAR PadRight
VAR PadBottom
VAR PadTop
METHOD Init()
METHOD Create()
ENDCLASS
METHOD VistaDialog:Init( oParent, oOwner, aPos, aSize, aPP, lVisible )
LOCAL nTmp := 0
::XbpDialog:Init( oParent, oOwner, aPos, aSize, aPP, lVisible )
IF "Vista" $ OS()
DwmIsCompositionEnabled( @nTmp )
IF nTmp != 0
::SetColorBG( XBPSYSCLR_TRANSPARENT )
ELSE
::SetColorBG( XBPSYSCLR_ACTIVETITLE )
ENDIF
ENDIF
::PadLeft := 0
::PadTop := 0
::PadRight := 0
::PadBottom := 0
RETURN self
METHOD VistaDialog:Create( oParent, oOwner, aPos, aSize, aPP, lVisible )
LOCAL aRect
LOCAL cBin
LOCAL nTmp := 0
IF ValType(lVisible) != "L"
lVisible := ::Visible
ENDIF
::XbpDialog:Create( oParent, oOwner, aPos, aSize, aPP, .F. )
IF "Vista" $ Os()
DwmIsCompositionEnabled( @nTmp )
IF nTmp != 0
cBin := L2Bin(::PadLeft) + L2Bin(::PadTop) + ;
L2Bin(::PadRight) + L2Bin(::PadBottom)
DwmExtendFrameIntoClientArea( ::GetHWND(), @cBin )
ENDIF
ENDIF
aRect := ::CurrentSize()
aRect := {0,0,aRect[1],aRect[2]}
aRect := ::CalcClientRect( aRect )
aRect[1] += ::PadLeft
aRect[2] += ::PadBottom
aRect[3] -= (::PadRight + ::PadLeft)
aRect[4] -= (::PadTop + ::PadBottom)
::DrawingArea:SetPosAndSize( {aRect[1],aRect[2]},{aRect[3],aRect[4]})
IF lVisible == .T.
::Show()
ENDIF
RETURN self
there is a new Constante for Vista(?)/Win7daan_vossebeld wrote:My practical experience is that with "non-Classic" themes I have to add about 7-9 pixels to the desired position. I see however no exact relation with the SM_CYCAPTION, SM_CYFRAME and SM_CYBORDER parameters of GetSystemMetrics (DLL).
Code: Select all
#define SM_CXDLGFRAME 7
#define SM_CYDLGFRAME 8
#define SM_CYMENU 15
#define SM_CYCAPTION 4
#define SM_CXPADDEDBORDER 92
LOCAL nWidthBorder := xbpGetSystemMetrics( SM_CXDLGFRAME )
LOCAL nHeightBorder := xbpGetSystemMetrics( SM_CYDLGFRAME )
LOCAL nBorderPadding := 0
IF OnOSversion() > 5 // Vista-Win7 DVW Aero
nBorderPadding := xbpGetSystemMetrics(SM_CXPADDEDBORDER)
ENDIF
...
FUNCTION xbpGetSystemMetrics( nValue )
RETURN DllCall( "USER32.DLL", DLL_STDCALL, "GetSystemMetrics", nValue )
greetings by OHR
Jimmy
Jimmy
-
- Posts: 11
- Joined: Fri Jan 29, 2010 1:37 am
Re: Origin 0,0 (in)dependent from themes?
Jimmy,
Thank you for your quick reaction.
I cannot use your first suggestion, because I fully work with eXpress commands. Further I know the new parameter (X-axis oriented) of your second suggestion. The returned value in Vista and XP for the themes "Windows Classic", "Windows Vista" and "Windows XP" are always 0.
Addition: My problem exists not only in Vista but also on XP with theme "Windows XP". In fact I am looking for the formula that calculates the topleft usable {n,0 } Y-axis setting.
Maybe Roger will also look to this.
Daan
Thank you for your quick reaction.
I cannot use your first suggestion, because I fully work with eXpress commands. Further I know the new parameter (X-axis oriented) of your second suggestion. The returned value in Vista and XP for the themes "Windows Classic", "Windows Vista" and "Windows XP" are always 0.
Addition: My problem exists not only in Vista but also on XP with theme "Windows XP". In fact I am looking for the formula that calculates the topleft usable {n,0 } Y-axis setting.
Maybe Roger will also look to this.
Daan
Re: Origin 0,0 (in)dependent from themes?
Due to the fact that the Windows coordinate system is reversed from the Xbase++ coordinate system, a coordinate of 0,0 must be recalculated based on the window height. Unfortunately, this calculation must also take into consideration the height of the title bar and and menu bar and that's what changes when you change themes.
When I originally wrote eXpress++, there was no ability to change themes under Win 98 so the title bar height and menu bar height was always constant. That has changed over the years, yet I have not done anything to compensate for it. I will make that fix in build 255. Nobody has ever asked for this so I have put it out of my mind. It requires making calls to the Windows API function GetSystemMetrics() to get the height of the title bar and the height of the menu bar.
The reason nobody has ever complained about this is because most eXpress++ users tend to use the FIT clause of DCREAD GUI. This causes the screen to automatically fit around the objects with a padding of 10 pixels. It makes all screens look good regardless of where your coordinates start.
You could try this:
DCGETOPTIONS FITPAD 0
DCREAD GUI FIT OPTIONS GetOptions
If that doesn't work for you, let me know which version of eXpress++ you are using and I will give you a workout (some changes to the code) that you can make until I release build 255.
When I originally wrote eXpress++, there was no ability to change themes under Win 98 so the title bar height and menu bar height was always constant. That has changed over the years, yet I have not done anything to compensate for it. I will make that fix in build 255. Nobody has ever asked for this so I have put it out of my mind. It requires making calls to the Windows API function GetSystemMetrics() to get the height of the title bar and the height of the menu bar.
The reason nobody has ever complained about this is because most eXpress++ users tend to use the FIT clause of DCREAD GUI. This causes the screen to automatically fit around the objects with a padding of 10 pixels. It makes all screens look good regardless of where your coordinates start.
You could try this:
DCGETOPTIONS FITPAD 0
DCREAD GUI FIT OPTIONS GetOptions
If that doesn't work for you, let me know which version of eXpress++ you are using and I will give you a workout (some changes to the code) that you can make until I release build 255.
The eXpress train is coming - and it has more cars.
-
- Posts: 11
- Joined: Fri Jan 29, 2010 1:37 am
Re: Origin 0,0 (in)dependent from themes?
Roger,
On the Y-axis it works, but on the X-axis the FIT clause introduces new problems. In some situations the window becomes to wide. Because it has to do with the FIT clause, I can't influence this. I could not find another (new) workaround for this problem.
I hope you will make a structural solution, using more GetSystemMetrics data. In some important windows of my program where I control all objects on pixel level I don't want to use the FIT clause. In many other windows I am happy with the FIT clause.
Daan
On the Y-axis it works, but on the X-axis the FIT clause introduces new problems. In some situations the window becomes to wide. Because it has to do with the FIT clause, I can't influence this. I could not find another (new) workaround for this problem.
I hope you will make a structural solution, using more GetSystemMetrics data. In some important windows of my program where I control all objects on pixel level I don't want to use the FIT clause. In many other windows I am happy with the FIT clause.
Daan
-
- Posts: 11
- Joined: Fri Jan 29, 2010 1:37 am
Re: Origin 0,0 (in)dependent from themes?
I am using Xbase 1.90.355 with eXpress 1.9.254.
Re: Origin 0,0 (in)dependent from themes?
Here is a modified _dcgetbx.prg.
Copy it to your \exp19\source\dclipx folder and rebuild dclipx.dll by running build19.bat or build19_sl1.bat
The change was made to line 1674.
Let me know if that works for you or if there is any other modification required.
Copy it to your \exp19\source\dclipx folder and rebuild dclipx.dll by running build19.bat or build19_sl1.bat
The change was made to line 1674.
Let me know if that works for you or if there is any other modification required.
- Attachments
-
- _dcgetbx.zip
- (77.87 KiB) Downloaded 1001 times
The eXpress train is coming - and it has more cars.
-
- Posts: 11
- Joined: Fri Jan 29, 2010 1:37 am
Re: Origin 0,0 (in)dependent from themes?
It did not directly work. I changed lines 1674-1676:
Old:
nStartRow := nParentHeight - nStartRow - ;
GetSystemMetrics(4) - GetSystemMetrics(15) - 8 - ;
aOptions[nGETOPT_ROWOFFSET]
New:
nStartRow := nParentHeight - nStartRow - ;
GetSystemMetrics(33) - GetSystemMetrics(4) - IIF(::isMenu,GetSystemMetrics(15),0) - 8 - ;
aOptions[nGETOPT_ROWOFFSET]
It works for theme "Windows Vista".
For the themes "Windows Classic" and "Windows XP" there are about 4-6 superfluous pixels between the menubar and the pushbuttons.
I think the "-8" in line 1675 was a fixed value for the GetSystemMetrics(33). But dropping the value gives also wrong results. Maybe you can explain this.
Daan
Old:
nStartRow := nParentHeight - nStartRow - ;
GetSystemMetrics(4) - GetSystemMetrics(15) - 8 - ;
aOptions[nGETOPT_ROWOFFSET]
New:
nStartRow := nParentHeight - nStartRow - ;
GetSystemMetrics(33) - GetSystemMetrics(4) - IIF(::isMenu,GetSystemMetrics(15),0) - 8 - ;
aOptions[nGETOPT_ROWOFFSET]
It works for theme "Windows Vista".
For the themes "Windows Classic" and "Windows XP" there are about 4-6 superfluous pixels between the menubar and the pushbuttons.
I think the "-8" in line 1675 was a fixed value for the GetSystemMetrics(33). But dropping the value gives also wrong results. Maybe you can explain this.
Daan
Re: Origin 0,0 (in)dependent from themes?
hi,
SM_CYSIZEFRAME = 33 ist incorrect !daan_vossebeld wrote:It did not directly work. I changed lines 1674-1676:Code: Select all
GetSystemMetrics(33)
this is "visual Style". use IsThemeActive()daan_vossebeld wrote:It works for theme "Windows Vista".
For the themes "Windows Classic" and "Windows XP" there are about 4-6 superfluous pixels between the menubar and the pushbuttons.
GetSystemMetrics http://msdn.microsoft.com/en-us/library ... 85%29.aspxdaan_vossebeld wrote:I think the "-8" in line 1675 was a fixed value for the GetSystemMetrics(33). But dropping the value gives also wrong results. Maybe you can explain this.
Code: Select all
#define SM_CXDLGFRAME 7
#define SM_CYDLGFRAME 8
#define SM_CYMENU 15
#define SM_CYCAPTION 4
#define SM_CXPADDEDBORDER 92
LOCAL nHeightTitlebar := xbpGetSystemMetrics( SM_CYCAPTION )
LOCAL nHeightMenubar := xbpGetSystemMetrics( SM_CYMENU )
LOCAL nWidthBorder := xbpGetSystemMetrics( SM_CXDLGFRAME )
LOCAL nHeightBorder := xbpGetSystemMetrics( SM_CYDLGFRAME )
LOCAL nBorderPadding := 0
IF OnOSVersion() > 5 // Vista-Win7 DVW Aero
nBorderPadding := xbpGetSystemMetrics(SM_CXPADDEDBORDER)
ENDIF
IF IsThemeActive() = .T.
....
ENDIF
greetings by OHR
Jimmy
Jimmy
Re: Origin 0,0 (in)dependent from themes?
Jimmy is correct.
The 8 pixels was to compensate for the border width.
I will read the metrics for the border width too.
I'll try to get you another update today.
The 8 pixels was to compensate for the border width.
I will read the metrics for the border width too.
I'll try to get you another update today.
The eXpress train is coming - and it has more cars.