Форум » GUI » Как делать одинаковые программы для Win7 и WinXP ? » Ответить

Как делать одинаковые программы для Win7 и WinXP ?

Andrey: Привет всем. Столкнулся с большой проблемой на Win7.... Программа собранная на Win8 - прекрасно отображается на WinXP, а на Win7 шрифты на форме уезжают.... Вид формы на Win8 и WinXP: Вид формы на Win7: Подскажите пожалуйста, что нужно делать чтобы изображения были нормальными для Win7 ?

Ответов - 12

SergKis: Andrey пишет: Подскажите пожалуйста, что нужно делать ... Надо все размеры в DLU : LONG WINAPI GetDialogBaseUnits(void); Затем переводим в Pixels UnitsToPixelsX(), UnitsToPixelsY() Аналогично работают шаблоны из диалоговых ресурсов от MS Этот механизм учитывает текущую настройку экрана PC у пользователя.

Andrey: SergKis пишет: Надо все размеры в DLU Не совсем понял... А можете пожалуйста на маленьком примере это продемонстрировать ? Или давайте я его сделаю, а Вы разъясните на нем ?

Dima: Andrey пишет: Не совсем понял... Если погуглить.... http://imho.com.ua/kb/sizez.html


SergKis: Andrey пишет:А можете пожалуйста на маленьком примере... Функции C. [pre2] HB_FUNC( UNITSTOPIXELSX ){ int UnitsX = hb_parnl(1); DWORD dwDLU = GetDialogBaseUnits(); int cx = MulDiv( UnitsX, LOWORD( dwDLU ), 4); hb_retnl( cx ); } HB_FUNC( UNITSTOPIXELSY ){ int UnitsY = hb_parnl(1); DWORD dwDLU = GetDialogBaseUnits(); int cy = MulDiv( UnitsY, HIWORD( dwDLU ), 8); hb_retnl( cy ); } [/pre2] Объект расчетный.[pre2] // --- Настроечные константы --- #include "minigui.ch" #include "hbclass.ch" CLASS Sets VAR oHK // Объект для работы с HotKey VAR oCargo // Эта переменная в Sets ни как не контролируется VAR xID // Идентификатор VAR oAppCfg // Для cIni{} настроек по всей программе * ------------ Отступы контролов на форме VAR nMrgLeft VAR nMrgTop VAR nMrgRight VAR nMrgBottom * ------------ Кнопки ------------- VAR nBtnWidth // Ширина кнопки VAR nBtnWidth15 // Ширина кнопки полуторная VAR nBtnWidth20 // Ширина кнопки двойная VAR nBtnHeight // Высота кнопки VAR nBtnGapsW // Растояние между кнопками по горизонтали VAR nBtnGapsH // Растояние между кнопками по вертикали * ------------ Поле ввода ------------- VAR nGetWidth05 // Ширина поля ввода для текста VAR nGetWidth // Ширина поля ввода для текста VAR nGetWidth15 // Ширина поля ввода для текста полуторная VAR nGetWidth20 // Ширина поля ввода для текста двойная VAR nGetWidth25 // Ширина поля ввода для текста двойная VAR nGetWidth30 // Ширина поля ввода для текста двойная VAR nGetWidth35 // Ширина поля ввода для текста VAR nGetWidth40 // Ширина поля ввода для текста VAR nGetWidthN6 // Ширина поля ввода для чисел размером 6 цифр VAR nGetWidthN12 // Ширина поля ввода для чисел размером 12 цифр VAR nGetWidthDT // Ширина поля ввода для дат VAR nGetWidthDT1 // Ширина поля ввода для дат для варианта с календарём VAR nGetWidthDT2 // Ширина поля ввода для дат для варианта с календарём и кнопкой VAR nGetHeight // Высота поля ввода по умолчанию VAR nGetHeight20 // Высота поля ввода по умолчанию для 2х строк одновременно VAR nGetGapsW // Растояние между поля ввода по горизонтали VAR nGetGapsH // Растояние между поля ввода по вертикали VAR nChbWidth // VAR nChbHeight // VAR nChbGapsW // VAR nChbGapsH // VAR nChbWidth15 // VAR nChbWidth20 // VAR cFontName // Имя фонта по умолчанию базовое VAR nDefFontSize // Задаваемый размер по умолчанию VAR nFontHeight // Высота символа по умолчанию базовое VAR nFontWidth // Ширина одного символа по умолчанию базовое _METHOD New() _METHOD UnitsDefault() // Поставить все параметры в DLU _METHOD UnitsToPixels() // Всё пересчитать на пикселы _METHOD FontDefault() _METHOD DLU2PixH( nHeight ) _METHOD DLU2PixW( nWidth ) _METHOD TextWidth( cText ) _METHOD SetCfg( cCfg ) // Установить файл конфигурации // Все 3 метода возвращают - только - Pix _METHOD W( uW, cText) // Получить по GET _METHOD G( cW ) // Получить промежутки между GET по горизонтали 'W' и вертикали 'H' _METHOD M( cM ) // Получить отступы между контролами // 'L' - левый // 'T' - верхний // 'R' - правый // 'B' - нижний _METHOD H( cH ) // Высота контрола ENDCLASS METHOD New() CLASS Sets ::oHK := hmgHotKey():New() Self:SetCfg() RETURN SELF METHOD SetCfg( cCfg ) CLASS Sets LOCAL cExe, cCt, cFont:="Arial", nHFont:=9 IF ! ValType(cCfg)=='C' // Определим по умолчанию : Текущий каталог + "HBK\INI" - имя как программа cExe := ExeName() cExe := subs( cExe, RAt('\', cExe) + 1) cCt := DiskName(0) + ':\' + CurDir() + "\HBK\INI\" cCfg := cCt + Left(cExe, Len(cExe)-3) + 'cfg' ENDIF ::oAppCfg := cIni():New( cCfg, [COMMON] ) // Сдесь можно прочитать из внешнего источника имя и размер // SELF:FontDefault( 13, GetTextFace() ) // 9, 'Arial' ) cFont := ::oAppCfg:Get("FontName", cFont) nHFont := Val( ::oAppCfg:Get("FontSize", hb_NToS(nHFont)) ) SELF:FontDefault( nHFont, cFont) SELF:UnitsDefault() SELF:UnitsToPixels() RETURN NIL METHOD W( uW, cText ) CLASS Sets LOCAL c, n, t IF ValType( uW )=='N' ; c := StrZero(uW,2) ELSEIF ValType( uW )=='C' ; c := uW ELSEIF ( t := ValType( cText ) ) $ 'CN' IF t == "N"; cText := repl("A", cText) ENDIF n := Self:TextWidth( cText ) IF n <= ::nGetWidth05 ; RETURN ::nGetWidth05 ELSEIF n <= ::nGetWidth ; RETURN ::nGetWidth ELSEIF n <= ::nGetWidth15 ; RETURN ::nGetWidth15 ELSEIF n <= ::nGetWidth20 ; RETURN ::nGetWidth20 ELSEIF n <= ::nGetWidth25 ; RETURN ::nGetWidth25 ELSEIF n <= ::nGetWidth30 ; RETURN ::nGetWidth30 ELSEIF n <= ::nGetWidth35 ; RETURN ::nGetWidth35 ELSEIF n <= ::nGetWidth40 ; RETURN ::nGetWidth40 ENDIF RETURN ::nGetWidth40 ELSE RETURN ::nGetWidth ENDIF IF c=='05' ; RETURN ::nGetWidth05 ELSEIF c=='10' ; RETURN ::nGetWidth ELSEIF c=='15' ; RETURN ::nGetWidth15 ELSEIF c=='20' ; RETURN ::nGetWidth20 ELSEIF c=='25' ; RETURN ::nGetWidth25 ELSEIF c=='30' ; RETURN ::nGetWidth30 ELSEIF c=='35' ; RETURN ::nGetWidth35 ELSEIF c=='40' ; RETURN ::nGetWidth40 ELSEIF c=='D1' ; RETURN ::nGetWidthDT1 ELSEIF c=='D2' ; RETURN ::nGetWidthDT2 ENDIF RETURN ::nGetWidth METHOD G( cG ) CLASS Sets //! Промежутки для Get IF ValType(cG)!='C' ; RETURN 0 ENDIF IF cG=='H1' ; RETURN Int( ::nGetGapsH ) // Целая ELSEIF cG=='H2' ; RETURN Int( ::nGetGapsH/2 ) // Половинка ELSEIF cG=='H3' ; RETURN Int( ::nGetGapsH/3 ) // 1/3 ELSEIF cG=='H23' ; RETURN Int( ::nGetGapsH ) - Int( ::nGetGapsH/3 ) // 2/3 ELSEIF cG=='H' ; RETURN Int( ::nGetGapsH ) // Целая ELSEIF cG=='W1' ; RETURN Int( ::nGetGapsW ) // Целая ELSEIF cG=='W2' ; RETURN Int( ::nGetGapsW/2 ) // Половинка ELSEIF cG=='W3' ; RETURN Int( ::nGetGapsW/3 ) // 1/3 ELSEIF cG=='W23' ; RETURN Int( ::nGetGapsW ) - Int( ::nGetGapsW/3 ) // 2/3 ELSEIF cG=='W' ; RETURN Int( ::nGetGapsW ) // Целая ENDIF RETURN 0 METHOD M( cM ) CLASS Sets //! Отступы IF ValType(cM)!='C' ; RETURN 0 ENDIF IF cM=='L1' ; RETURN Int( ::nMrgLeft ) // Целая ELSEIF cM=='L2' ; RETURN Int( ::nMrgLeft/2 ) // Половинка ELSEIF cM=='L3' ; RETURN Int( ::nMrgLeft/3 ) // 1/3 ELSEIF cM=='L23' ; RETURN Int( ::nMrgLeft ) - Int( ::nMrgLeft/3 ) // 2/3 ELSEIF cM=='L' ; RETURN Int( ::nMrgLeft ) // Целая ELSEIF cM=='T1' ; RETURN Int( ::nMrgTop ) // Целая ELSEIF cM=='T2' ; RETURN Int( ::nMrgTop/2 ) // Половинка ELSEIF cM=='T3' ; RETURN Int( ::nMrgTop/3 ) // 1/3 ELSEIF cM=='T23' ; RETURN Int( ::nMrgTop ) - Int( ::nMrgTop/3 ) // 2/3 ELSEIF cM=='T' ; RETURN Int( ::nMrgTop ) // Целая ELSEIF cM=='R1' ; RETURN Int( ::nMrgRight ) // Целая ELSEIF cM=='R2' ; RETURN Int( ::nMrgRight/2 ) // Половинка ELSEIF cM=='R3' ; RETURN Int( ::nMrgRight/3 ) // 1/3 ELSEIF cM=='R23' ; RETURN Int( ::nMrgRight ) - Int( ::nMrgRight/3 ) // 2/3 ELSEIF cM=='R' ; RETURN Int( ::nMrgRight ) // Целая ELSEIF cM=='B1' ; RETURN Int( ::nMrgBottom ) // Целая ELSEIF cM=='B2' ; RETURN Int( ::nMrgBottom/2 ) // Половинка ELSEIF cM=='B3' ; RETURN Int( ::nMrgBottom/3 ) // 1/3 ELSEIF cM=='B23' ; RETURN Int( ::nMrgBottom ) - Int( ::nMrgBottom/3 ) // 2/3 ELSEIF cM=='B' ; RETURN Int( ::nMrgBottom ) // Целая ENDIF RETURN 0 METHOD H( cH ) CLASS Sets //! Высота контрола для Get,Btn,Chb IF ValType(cH)!='C' ; RETURN ::nGetHeight ENDIF IF cH=='G' ; RETURN Int( ::nGetHeight ) // Целая ELSEIF cH=='G2' ; RETURN Int( ::nGetHeight20 ) // Половинка ELSEIF cH=='B' ; RETURN Int( ::nBtnHeight ) // 1/3 ELSEIF cH=='C' ; RETURN Int( ::nChbHeight ) ENDIF RETURN ::nGetHeight METHOD UnitsDefault() CLASS Sets //! Все размеры в DLU : LONG WINAPI GetDialogBaseUnits(void); //! Затем переводим в Pixels UnitsToPixelsX(), UnitsToPixelsY() //! Аналогично работают шаблоны из диалоговых ресурсов от MS //! Этот механизм учитывает текущую настройку экрана PC у пользователя. * ------ Отступы от края формы ::nMrgLeft := 7 ::nMrgTop := 7 ::nMrgRight := 7 ::nMrgBottom := 7 * ----- Командная кнопка ::nBtnWidth := 50 // Ширина кнопки по умолчанию ::nBtnHeight := 14 // Высота кнопки по умолчанию ::nBtnGapsW := 4 // Растояние между кнопками по горизонтали ::nBtnGapsH := 4 // Растояние между кнопками по вертикали ::nBtnWidth15 := ::nBtnWidth + int(::nBtnWidth/2) // Полуторная ширина ::nBtnWidth20 := ::nBtnWidth + ::nBtnWidth // Двойная ширина * ----- Поля ввода ------ ::nGetWidth := 50 // Ширина полями ввода по умолчанию ::nGetHeight := 14 // Высота полями ввода по умолчанию ::nGetHeight20 := 24 // Высота полями ввода по умолчанию для 2х строк ::nGetGapsW := 4 // Растояние между полями ввода по горизонтали ::nGetGapsH := 4 // Растояние между полями ввода по вертикали ::nGetWidth05 := 25 ::nGetWidth15 := ::nGetWidth + ::nGetWidth05 // int(::nGetWidth/2) // Полуторная ширина ::nGetWidth20 := ::nGetWidth + ::nGetWidth // Двойная ширина ::nGetWidth25 := ::nGetWidth20 + ::nGetWidth05 ::nGetWidth30 := ::nGetWidth20 + ::nGetWidth ::nGetWidth35 := ::nGetWidth20 + ::nGetWidth15 ::nGetWidth40 := ::nGetWidth20 + ::nGetWidth20 ::nGetWidthN6 := 25 // Ширина поля ввода для чисел из 6 цифр ::nGetWidthN12 := 50 // Ширина поля ввода для чисел из 12 цифр ::nGetWidthDT := 50 // Ширина поля ввода для дат ::nGetWidthDT1 := 60 // Ширина поля ввода для дат 50 * 1.2 ::nGetWidthDT2 := 75 // Ширина поля ввода для дат 50 * 1.3 * ----- CheckBox ::nChbWidth := 50 // Ширина галочки по умолчанию просто не меняем ::nChbHeight := 10 // Высота галочки по умолчанию ::nChbGapsW := 4 // Растояние между кнопками по горизонтали это как нужно ::nChbGapsH := 4 // Растояние между галочками по вертикали и может быть 3 от Label ::nChbWidth15 := ::nChbWidth + int(::nChbWidth/2) // Полуторная ширина ::nChbWidth20 := ::nChbWidth + ::nChbWidth // Двойная ширина RETURN .T. METHOD DLU2PixH( nHeight ) CLASS Sets RETURN Round( (UnitsToPixelsY( nHeight ) * 13)/15, 0) METHOD DLU2PixW( nWidth ) CLASS Sets RETURN Round( (UnitsToPixelsX( nWidth ) * 13)/15, 0) METHOD UnitsToPixels() CLASS Sets * ------ Отступы для контролов от края формы ::nMrgLeft := Self:DLU2PixW( ::nMrgLeft ) ::nMrgTop := Self:DLU2PixH( ::nMrgTop ) ::nMrgRight := Self:DLU2PixW( ::nMrgRight ) ::nMrgBottom := Self:DLU2PixH( ::nMrgBottom ) * ------ Размеры кнопок ::nBtnWidth := Self:DLU2PixW( ::nBtnWidth ) ::nBtnHeight := Self:DLU2PixH( ::nBtnHeight ) ::nBtnGapsW := Self:DLU2PixW( ::nBtnGapsW ) ::nBtnGapsH := Self:DLU2PixH( ::nBtnGapsH ) ::nBtnWidth15 := Self:DLU2PixW( ::nBtnWidth15 ) ::nBtnWidth20 := Self:DLU2PixW( ::nBtnWidth20 ) * ----- Размеры для полей ввода ::nGetWidth := Self:DLU2PixW( ::nGetWidth ) ::nGetHeight := Self:DLU2PixH( ::nGetHeight ) ::nGetHeight20 := Self:DLU2PixH( ::nGetHeight20 ) ::nGetGapsW := Self:DLU2PixW( ::nGetGapsW ) ::nGetGapsH := Self:DLU2PixH( ::nGetGapsH ) ::nGetWidth05 := Self:DLU2PixW( ::nGetWidth05 ) ::nGetWidth15 := Self:DLU2PixW( ::nGetWidth15 ) ::nGetWidth20 := Self:DLU2PixW( ::nGetWidth20 ) ::nGetWidth25 := Self:DLU2PixW( ::nGetWidth25 ) ::nGetWidth30 := Self:DLU2PixW( ::nGetWidth30 ) ::nGetWidth35 := Self:DLU2PixW( ::nGetWidth35 ) ::nGetWidth40 := Self:DLU2PixW( ::nGetWidth40 ) ::nGetWidthN6 := Self:DLU2PixW( ::nGetWidthN6 ) ::nGetWidthN12 := Self:DLU2PixW( ::nGetWidthN12 ) ::nGetWidthDT := Self:DLU2PixW( ::nGetWidthDT ) ::nGetWidthDT1 := Self:DLU2PixW( ::nGetWidthDT1 ) ::nGetWidthDT2 := Self:DLU2PixW( ::nGetWidthDT2 ) * ------- Размеры для Галочек ::nChbWidth := Self:DLU2PixW( ::nChbWidth ) ::nChbHeight := Self:DLU2PixH( ::nChbHeight ) ::nChbGapsW := Self:DLU2PixW( ::nChbGapsW ) ::nChbGapsH := Self:DLU2PixH( ::nChbGapsH ) ::nChbWidth15 := Self:DLU2PixW( ::nChbWidth15 ) ::nChbWidth20 := Self:DLU2PixW( ::nChbWidth20 ) RETURN .T. METHOD FontDefault( nHeight, cFont, cChar ) CLASS Sets //! nHeight - размер фонта по умолчанию LOCAL n:=30, cTx, hFont cChar := iif(ValType(cChar)=='C', cChar, 'A') ::cFontName := cFont ::nDefFontSize := nHeight cTx := Repl(cChar, n) hFont := InitFont(::cFontName, ::nDefFontSize) // C_Font.c функция ::nFontHeight := GetTextHeight( 0, cTx, hFont) ::nFontWidth := GetTextWidth( 0, cTx, hFont)/n DeleteObject ( hFont ) // Чистим // MsgBox( GetTextFace() + Chr(10) + Str( GetSysTextHeight() ) + Chr(10) + Str( ::nFontHeight ) ) RETURN .T. METHOD TextWidth( cText ) CLASS Sets LOCAL hFont, nWidth hFont := InitFont( ::cFontName, ::nDefFontSize) // C_Font.c функция nWidth := GetTextWidth( 0, cText, hFont) DeleteObject ( hFont ) // Чистим RETURN nWidth [/pre2] В программе:[pre2] oSets := Sets():New() // Общие установки для размеров GUI _HMG_DefaultFontName := oSets:cFontName // 'Arial' BAA 5-Май-2012 12:25:31 _HMG_DefaultFontSize := oSets:nDefFontSize // 9 BAA 5-Май-2012 12:25:37 ... далее в формах для Width и Height используются переменные из объекта, например nBtnHeight, nBtnWidth, nBtnWidth20, nGetWidth, nGetHeight,... смотри коментарии к переменным. как-то так вот ... [/pre2]

Andrey: Блин, засада.... Столько всего нужно делать.... Целое искусство....

SergKis: Andrey пишет:Блин, засада.... Столько всего нужно делать.. Сделанное один раз можно использовать много раз. Это к тому, что начав так писать - потом будете удивляться - как раньше писали по другому ... !?

Andrey: SergKis пишет: потом будете удивляться - как раньше писали по другому ... !? Это точно... Глаза боятся, руки делают...

alex_II: Поделитесь готовым маленьким примером, использующим эту технологию. Заранее спасибо

SergKis: alex_II пишет:Поделитесь готовым ... маленького нет - все в объектах. а делать примерно так: [pre2] oSets := Sets():New() // Общие установки для размеров GUI _HMG_DefaultFontName := oSets:cFontName _HMG_DefaultFontSize := oSets:nDefFontSize ... oSets:W(...) - дает width контролов oSets:H(...) - дает height контролов oSets:G('W...') - дает width расстояния между контролами oSets:G('H...') - дает height расстояния между контролами oSets:M(...) - дает отступы Top,Right,Bottom,Left детально см. текст класса ... y := nRow x := nCol DEFINE LABEL &(cLbl) ROW y COL x // WIDTH oSets:W( , cCaption) // подберет подходящий размер от текста // WIDTH oSets:W( , len(cCaption)) // подберет подходящий размер от текста: // repl('A', nLen) // WIDTH oSets:W('05') // 0.5 длины, или oSets:nGetWidth05 // WIDTH oSets:W('10') // 1.0 длины, или oSets:nGetWidth10 WIDTH oSets:W('20') // двойная длина, или oSets:nGetWidth20 HEIGHT oSets:H() // высота , или oSets:::nGetHeight VALUE cCaption END LABEL h := GetControlHandle(cLbl, cForm) x += GetWihdowWidth(h)+oSets:G('W') // ширина контрола+расстояние между конролами по width DEFINE GETBOX &(cGet) ROW y COL x WIDTH oSets:W('40') // 2 * двойная длина, или oSets:nGetWidth40 HEIGHT oSets:H() // высота , или oSets:::nGetHeight VALUE cValue IF ValType( cAction )=='C' ACTION &cAction ENDIF END GETBOX h := GetControlHandle(cGet, cForm) y += GetWihdowHeight(h)+oSets:G('H') // высота контрола+расстояние между конролами по height x := nCol BROWSE: ROW y COL x ... HEADERS { 'Code' , 'First Name' , 'Last Name' , ... } ; WIDTHS { oSets:W('10'), oSets:W('20'), oSets:W('15'), ... } ; ... или WIDTHS { oSets:W( , Max(hb_FieldLen(FieldPos('Code')) , 'Поле Code')), ; oSets:W( , Max(hb_FieldLen(FieldPos('FirstName'), 'Поле First Name')), ; oSets:W('15'), ... } ; удобнее убрать DEFINE в функции или классы. [/pre2]

alex_II: спасибо и на этом...

SergKis: alex_II пишет:спасибо и на этом... class работал в VO 2.0, 2.5, 2.7, ~ 10 лет. перенесен в hb без изменений для совместимости текстов. примеры были ненужны. гляньте личку.

alex_II: Большое спасибо за помощь



полная версия страницы