Convert FBedit Form-Designer Units into Pixels

Windows specific questions.
Post Reply
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Convert FBedit Form-Designer Units into Pixels

Post by St_W »

Hi,

I'd like to calculate the position of a control when a Windows gets resized, because the Controls within this windows should change their size too.
I use the Win32-API Function "MoveWindow" which asks for the coordinates of the controls in Pixels.

Code: Select all

Case WM_SIZE
	GetClientRect(hWnd,@rect)
	MoveWindow(GetDlgItem(hWnd, btnEnd), x1, y1, x2, y2, TRUE)
Which unit system does the Form-Designer of FBedit use?
How do I convert it into pixels?

or

Is there an better solution than converting the value into pixels?


Thanks,
St_W
Galeon
Posts: 563
Joined: Apr 08, 2009 5:30
Location: Philippines
Contact:

Post by Galeon »

fbedit creates dialogs not normal windows, you need to find the equivalent of pixels and the font you used to identify the pixels (i can't understand what i posted...)
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

I think in the dialog editor the coordinates and width and height are expressed in pixels, but in the dialog template they are stored as Dialog Template Units (DTUs). There are functions that, within limits, will allow you to convert between DTUs and pixels, but for what you are trying to do I can see no need. For the WM_SIZE notification the new width and height of the client area, in pixels, are stored in the lParam parameter (width in the low-order word and height in the high-order word). For the controls, you can use the GetWindowRect function to get the position of the control in screen (pixel) coordinates, and to calculate the width and height of the control (in pixels). To convert from screen coordinates to client coordinates you can use the ScreenToClient function.
McLovin
Posts: 82
Joined: Oct 21, 2008 1:15
Contact:

Post by McLovin »

GetWindowRect to get the full rect size of the control( client and non-client areas).

Use MapWindowPoints to convert the rect found via GetWindowRect from screen (desktop) coordinates to client area offset coordinates.
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Post by St_W »

I'm a Microsoft-Windows-Programming-beginner.

I'd like to resize the Controls (Buttons, Textboxes, Listboxes, Labels, etc.) when the outer Window (maybe Dialog? I don't know the difference yet.) gets resized.

Code: Select all

#Include Once "windows.bi"
#include once "win/commctrl.bi"
#include once "win/commdlg.bi"

InitCommonControls()

Dim Shared hInstance As HMODULE
Dim Shared hWnd_FrmMain as HWND

Declare Function frmMain_Proc(ByVal hWnd As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer

hInstance=GetModuleHandle(NULL)
DialogBoxParam(hInstance, Cast(ZString Ptr,frmMain), NULL, @frmMain_Proc, NULL)

Function frmMain_Proc(ByVal hWnd As HWND,ByVal uMsg As UINT,ByVal wParam As WPARAM,ByVal lParam As LPARAM) As Integer
	Dim As Long id, Event, x, y
	Dim hBtn As HWND
	Dim hWndTmp as HWND
	Dim rect As RECT
	
	Select Case uMsg
		
		Case WM_INITDIALOG
			hWnd_FrmMain = hWnd
			
		Case WM_CLOSE
            EndDialog(hWnd, 0)
            ExitProcess(0)

			
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				
				Case btnEnde
					SendMessage(hWnd, WM_CLOSE, 0,0)

			End Select
			
			
		Case WM_SIZE
			GetClientRect(hWnd,@rect)
			MoveWindow(GetDlgItem(hWnd, btnClose), rect.right-55, rect.top+6, 50, 15, TRUE)

		Case Else
			Return false
			
			
	End Select
	
	Return TRUE

End Function
The Dialog/Window (however this thing is called) is stored in a .rc-file and I've created it using the Form-Designer of FBedit.

Up to now I've looked up the position of the Button in FBedit-Designer and used this values for the MoveWindow function, but if I use the same values as in FormDesigner the position of the buttons don't match.

How can I resize the button and change the position so that the proportions stay the same? (eg if the button is in designer at X:5, Y:4 which coordinates are this in the dialog?)
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Post by Loe »

St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Post by St_W »

Thank you very much!

The program rc2code is great, but doesn't create an example how the controls are resized. But the function "MapDialogRect" is really great - i didn't know that such a function existed. The conversion from DLU into Pixels works without problems (up to now :-) ).

I've read in the thread you've put a link to, that you've used wxWidgets. I've also tried wxW, but then switched to the windows API, because the wrapper for wxW wasn't satisfying and I had problems with Unix systems (see http://www.freebasic.net/forum/viewtopic.php?p=116282).

Did you use wxW on Unix-Systems? If someone could explain me how wxW works i would use wxW, because it's portable to unix systems and the programs will run on Microsoft Windows and unix-systems while Win32 API programs only run on Microsoft Windows.

btw: my skills in fb-gui programming are low
KetilO
Posts: 416
Joined: Sep 22, 2005 21:48
Location: Norway
Contact:

Post by KetilO »

Hi St_W

Here is a way to convert from dialog units to pixels when the dialog has a given font.

Code: Select all


#Include Once "windows.bi"

Type DIALOGTEMPLATE
	style As Integer
	exstyle As Integer
	cdit As Short
	x As Short
	y As Short
	cx As Short
	cy As Short
	menu As Short
	cl As Short
	caption As Short
	pointsize As Short
	facename As WString*33
End Type

Dim Shared hInstance As HINSTANCE
Dim Shared hDlg As HWND
Dim Shared pixx As Integer
Dim Shared pixy As Integer
Dim Shared dt As DIALOGTEMPLATE

Function DlgProc(hWin As HWND,uMsg As UInteger,wParam As WPARAM,lParam As LPARAM) As Integer
	Dim rect As RECT

	If uMsg=WM_INITDIALOG Then
		GetClientRect(hWin,@rect)
		pixx=rect.right	' The width of the dialog in pixels
		pixy=rect.bottom	' The height of the dialog in pixels
		Return FALSE
	Else
		Return FALSE
	EndIf
	Return TRUE

End Function

Const FontName As String="MS Sans Serif"
Const FontSize As Integer=8

' Get the instance handle
hInstance=GetModuleHandle(0)
' Setup the DIALOGTEMPLATE
dt.style=WS_CAPTION Or DS_SETFONT
dt.exstyle=0
dt.x=0						' X Position
dt.y=0						' Y position
dt.cx=256					' Width in dialog units
dt.cy=256					' Height in dialog units
dt.menu=0					' No menu
dt.cl=0						' No class
dt.caption=0				' No caption
dt.pointsize=FontSize	' Font size in points
MultiByteToWideChar(CP_ACP,0,@FontName,Len(FontName),@dt.facename,32) ' Font name in wide chars

' Create the dialog
hDlg=CreateDialogIndirect(hInstance,Cast(Any Ptr,@dt),0,@DlgProc)
' Destroy the dialog
DestroyWindow(hDlg)

' Show the results
Print "With the given font " & FontName & "," & FontSize
Print
Print "256 dux equals " & Str(pixx) & " pixels"
Print "256 duy equals " & Str(pixy) & " pixels"
Print
Print "A button positioned at Left=93 and Top=72 and with a size"
Print "Width=48 and Height=15 in dialog units"
Print "would be positioned at Left=" & Str(Int(93*pixx/256)) & " and Top=" & Str(Int(72*pixy/256)) & " and have a size"
Print "Width=" &  Str(Int(48*pixx/256)) & " and Height=" &  Str(Int(15*pixy/256)) & " in pixels"

Sleep
KetilO
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Post by Loe »

@st_w
Sorry i missed your reply,
in case you still need the answer,
The program rc2code is great, but doesn't create an example how the controls are resized.
Rc2Code wx resize generated code sample:

Code: Select all

'================================================
'Code generated by RC2CODE - RC To Code Generator
'Very first stage project, use at your own risk
'Contact Loe at webhasta[at]telkom.net
'================================================


#include once "wx-c/wx.bi"
'#include once "C:\FbEdit\Projects\wxresize\wxresize.bi" 'exported names of resource file
'=========================================================================
'Defined constant in .rc file. 
'=========================================================================
type trect
	as integer x,y,w,h
end type

type tpoint
	as integer x,y
end type

#define wxCLOSE_BOX &h1000
#define IDD_DLG1 1000
#define IDC_EDT1 1001
#define IDC_BTN1 1002
#define IDC_CBO1 1003

'=========================================================================
'Include file of control
'=========================================================================

'=========================================================================
'Global variable
'=========================================================================
dim shared app as wxApp ptr 
dim shared as wxDialog ptr IDD_DLG1ptr

'========================================================================
'Dialog callback procedure declaration
'=========================================================================
declare Function IDD_DLG1_Init(byval parent as uinteger) as integer 
declare function IDD_DLG1_OnExit() as integer
declare sub IDD_DLG1_IDC_CBO1_Sample(Byval CTLIDptr as wxCombobox ptr)
declare Sub IDD_DLG1_OnSize(byval event as wxEvent ptr, byval iListener as integer)
declare sub IDD_DLG1_IDC_BTN1_Clicked(byval event as wxEvent ptr, byval iListener as integer)
declare SUB IDD_DLG1_IDC_CBO1_Selected(byval event as wxEvent ptr, byval iListener as integer)

sub IDD_DLG1_IDC_CBO1_Sample(Byval CTLIDptr as wxCombobox ptr)
	wxCombobox_append(CTLIDptr,strptr("row 0"))
	wxCombobox_append(CTLIDptr,strptr("row 1"))
	wxCombobox_append(CTLIDptr,strptr("row 2"))
	wxCombobox_append(CTLIDptr,strptr("row 3"))
end sub

Sub IDD_DLG1_OnSize(byval event as wxEvent ptr, byval iListener as integer)
	Dim sz As trect
	dim as wxWindow ptr wxw
	wxw=wxEvent_GetEventObject(event)
	wxWindow_GetClientRect(wxw,@sz)
	wxWindow_SetSize(wxWindow_FindWindowId(wxw,IDC_EDT1), sz.x,sz.y,sz.w,sz.h-20,1)
	wxWindow_SetSize(wxWindow_FindWindowId(wxw,IDC_BTN1), sz.x,sz.y+sz.h-20,sz.w\2,20,1)
	wxWindow_SetSize(wxWindow_FindWindowId(wxw,IDC_CBO1), sz.x+sz.w\2,sz.y+sz.h-20,sz.w\2,20,1)
end sub
sub IDD_DLG1_IDC_BTN1_Clicked(byval event as wxEvent ptr, byval iListener as integer)
	wxMsgBox( 0,"IDC_BTN1_Clicked","Event",0,wxSize(-1,-1))	
end sub
SUB IDD_DLG1_IDC_CBO1_Selected(byval event as wxEvent ptr, byval iListener as integer)
	dim wxCb as wxCombobox ptr 
	wxCb=wxEvent_GetEventObject(event)	
	wxMsgBox( 0,"IDC_CBO1_Selected " & *wxString_mb_str(wxComboBox_GetStringSelection(wxcb)),"Event",0,wxSize(-1,-1))	
end Sub


'=========================================================================
'Initial code of control
'=========================================================================

app = wxApp( )
wxApp_RegisterVirtual( app, @IDD_DLG1_init, @IDD_DLG1_OnExit)
wxApp_Run(0,0) 	
end 0

'=========================================================================
'Dialog callback procedure
'=========================================================================
Function IDD_DLG1_Init(byval parent as uinteger) as integer 
	dim as wxFrame ptr IDD_DLG1_FramePtr = wxFrame( )	
	wxFrame_Create(IDD_DLG1_FramePtr,0,-1,"IDD_DLG",wxSize(15,16),wxSize(233,190),wxRESIZE_BORDER or wxCAPTION or wxSYSTEM_MENU or wxClose_Box,"frame")
	IDD_DLG1ptr = wxPanel( )
	wxPanel_Create(IDD_DLG1ptr,IDD_DLG1_FramePtr,IDD_DLG1,0,0,0,0)
	wxEvtHandler_proxy(IDD_DLG1ptr, @IDD_DLG1_OnSize)
	wxEvtHandler_connect(IDD_DLG1ptr, wxEvent_EVT_SIZE( ),IDD_DLG1,-1,0)		
	/'rem above code for child dialog, and open following rem'/ 
	'IDD_DLG1ptr = wxDialog()
	'wxDialog_Create(IDD_DLG1ptr,parent,IDD_DLG1,"IDD_DLG",wxSize(15,16),wxSize(233,190),wxRESIZE_BORDER or wxCAPTION or wxSYSTEM_MENU or wxClose_Box,"")
	dim as wxTextCtrl ptr IDC_EDT1ptr=wxTextCtrl()
	wxTextCtrl_Create(IDC_EDT1ptr,IDD_DLG1ptr,IDC_EDT1,"",wxSize(0,0),wxSize(225,137),0 or 0,0,0)
	dim as wxButton ptr IDC_BTN1ptr = wxButton( )
	wxButton_Create(IDC_BTN1ptr,IDD_DLG1ptr,IDC_BTN1,"IDC_BTN",wxsize(0,141),wxsize(104,20),0 or 0,0,0) 
	'connect the button to the button event handler sub
	wxEvtHandler_proxy(IDC_BTN1ptr, @IDD_DLG1_IDC_BTN1_Clicked)
	wxEvtHandler_connect(IDC_BTN1ptr, wxEvent_EVT_COMMAND_BUTTON_CLICKED( ),IDC_BTN1,-1,0)
	dim as wxCombobox ptr IDC_CBO1ptr=wxCombobox()
	wxCombobox_Create(IDC_CBO1ptr,IDD_DLG1ptr,IDC_CBO1,"",wxSize(108,141),wxSize(117,24),0,0,wxCB_DROPDOWN,0,0)
	IDD_DLG1_IDC_CBO1_Sample(IDC_CBO1ptr)
	'connect the combobox to the combobox event handler sub
	wxEvtHandler_proxy(IDC_CBO1ptr, @IDD_DLG1_IDC_CBO1_Selected)
	wxEvtHandler_connect(IDC_CBO1ptr, wxEvent_EVT_COMMAND_COMBOBOX_SELECTED(),IDC_CBO1,-1,0)

	'wxWindow_CenterOnScreen(IDD_DLG1Ptr, wxBOTH )
	/'rem below code for child dialog, and open above rem'/
	wxWindow_CenterOnScreen(IDD_DLG1_FramePtr, wxBOTH )
	wxWindow_Show(IDD_DLG1_FramePtr, 1 )
	function = wxApp_OnInit(app)
End Function
function IDD_DLG1_OnExit() as integer
	function = wxApp_OnExit(app)	
end function

GetClientRect=wxWindow_GetClientRect
MoveWindow=wxWindow_SetSize

to use wx in Linux you cant instal it "abc" as in windows,
i've used FreeBASIC and wx in Ubuntu, but then I switch again to windows
because some hardware installation problem, not with FB nor wx reason.

I'll be back about how to install wx in linux, if I can find it :-(
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Post by St_W »

Thanks for your answer.

I've now decided to use pure Win-API for my first GUI programs, but I'm sure - sooner or later - I'll try wxWidgets again. But until that I want to learn using the Win-API.

[quote = "Loe"]to use wx in Linux you cant instal it "abc" as in windows,
i've used FreeBASIC and wx in Ubuntu, but then I switch again to windows
because some hardware installation problem, not with FB nor wx reason.

I'll be back about how to install wx in linux, if I can find it :-([/quote]

Although I nearly never use any Linux installing wxWidgets wasn't a problem. The program also worked, but it behaved strange. For example: I didn't manage to get or set a Textbox-Text on Linux. The program-code that worked fine on Windows didn't work on Linux.
Post Reply