解決Raize日曆控制元件顯示的問題
近自己的程式被測試人員發現一個小問題,就是程式中的日曆選擇框,顯示中的“星期一、星期二。。。。”都顯示成了“星。。。。。”,我自己看了程式碼,原來是raize的控制元件問題,並且無論用4.x版本還是5.x版本,問題都依然存在。沒辦法,就在網上找找看,結果還是找到了,原來需要修改下原始碼檔案:
修改:RzPopups.pas,該檔案在raize目錄下的source子目錄,修改其中的procedure TRzCalendar.Paint這個過程,下面是修改後的程式碼:
procedure TRzCalendar.Paint; var S, S2, F: string; R, WR, SelRect, DaysRect, DayR: TRect; I, J, WN, Offset, MaxLen, SaveFontSize: Integer; DrawDate: TDateTime; Year, Month, Day, ViewMonth, ViewYear: Word; DayColor, DayFontColor, TempC, C: TColor; DayFontStyle: TFontStyles; CustomDayFormat: Boolean; PMBoldDays, NMBoldDays, CMBoldDays, BoldDaysMask: Cardinal; ArrowFont: TFont; ButtonsVisible, DrawFlat: Boolean; Areas: TRzCalendarAreas; procedure DrawHorizontalLine( ALeft, ARight, AHeight: Integer ); var ElementDetails: TThemedElementDetails; begin if FThemeAware and ThemeServices.ThemesEnabled then begin ElementDetails := ThemeServices.GetElementDetails( ttbSeparatorVertNormal ); ThemeServices.DrawElement( Canvas.Handle, ElementDetails, Rect( ALeft, AHeight, ARight, AHeight + 3 ) ); end else begin Canvas.Pen.Color := FCalendarColors.Lines; Canvas.MoveTo( ALeft, AHeight ); Canvas.LineTo( ARight, AHeight ); end; end; procedure DrawVerticalLine( ATop, ABottom, ALeft: Integer ); var ElementDetails: TThemedElementDetails; begin if FThemeAware and ThemeServices.ThemesEnabled then begin ElementDetails := ThemeServices.GetElementDetails( ttbSeparatorNormal ); ThemeServices.DrawElement( Canvas.Handle, ElementDetails, Rect( ALeft, ATop, ALeft + 3, ABottom ) ); end else begin Canvas.Pen.Color := FCalendarColors.Lines; Canvas.MoveTo( ALeft, ATop ); Canvas.LineTo( ALeft, ABottom ); end; end; begin {= TRzCalendar.Paint =} if FThemeAware and ThemeServices.ThemesEnabled then begin C := GetXPThemeColor( xptcEditBorder ); R := DrawBox( Canvas, ClientRect, C ); Canvas.Brush.Color := Color; Canvas.FillRect( R ); end else inherited; DrawFlat := BorderOuter in [ fsFlat, fsFlatBold, fsFlatRounded ]; CalcAreas( Areas ); // Draw Month and Year Bar if ( [ ceMonth, ceYear ] * FElements ) <> [ ] then begin if FShowDays then begin R := Areas[ caYear ]; if FThemeAware and ThemeServices.ThemesEnabled then begin GetGradientPanelColors( gcsMSOffice, TempC, C ); end else begin if not DrawFlat then R := DrawBorder( Canvas, R, fsPopup ); C := FButtonColor; end; Canvas.Brush.Color := C; Canvas.FillRect( R ); end; SetBkMode( Canvas.Handle, Windows.Transparent ); if ceArrows in FElements then begin ArrowFont := TFont.Create; try ArrowFont.Name := 'Marlett'; ArrowFont.Size := Font.Size + 4; Canvas.Font.Assign( ArrowFont ); finally ArrowFont.Free; end; DrawStringCentered( Canvas, '3', Areas[ caLeftArrow ] ); // Draw Left Arrow DrawStringCentered( Canvas, '4', Areas[ caRightArrow ] ); // Draw Right Arrow end; // Draw month and year Canvas.Font.Assign( Font ); Canvas.Font.Color := FButtonFontColor; F := 'mmmm'; if ceYear in FElements then F := F + ' yyyy'; DrawStringCentered( Canvas, FormatDateTime( F, ViewDate ), Areas[ caYear ] ); end; if FShowDays then begin ButtonsVisible := False; // Draw Today button if ceTodayButton in FElements then begin if FCaptionTodayBtn <> '' then S := FCaptionTodayBtn else S := '今日'; DrawButton( Canvas, Areas[ caTodayButton ], S, FButtonColor, FButtonFontColor, DrawFlat, ( FPressedArea = caTodayButton ) and ( FOverArea = caTodayButton ), FThemeAware ); ButtonsVisible := True; end; // Draw Clear Button if ceClearButton in FElements then begin if FCaptionClearBtn <> '' then S := FCaptionClearBtn else S := '清除'; DrawButton( Canvas, Areas[ caClearButton ], S, FButtonColor, FButtonFontColor, DrawFlat, ( FPressedArea = caClearButton ) and ( FOverArea = caClearButton ), FThemeAware ); ButtonsVisible := True; end; // Draw Day of Week Headings if ceDaysOfWeek in FElements then begin Canvas.Brush.Color := Color; Canvas.Font.Color := FCalendarColors.DaysOfWeek; SaveFontSize := Canvas.Font.Size; Canvas.Font.Size := SaveFontSize - 1; R := Bounds( Areas[ caDaysOfWeek ].Left, Areas[ caDaysOfWeek ].Top - 1, FCellSize.X - 2, FCellSize.Y ); MaxLen := GetMaxShortDayNameLength; for I := 0 to 6 do begin J := FFirstDay + I + 2; if J > 7 then Dec( J, 7 ); S := ShortDayNames[ J ]; if j=1 then s:='日'; if j=2 then s:='一'; if j=3 then s:='二'; if j=4 then s:='三'; if j=5 then s:='四'; if j=6 then s:='五'; if j=7 then s:='六'; if MaxLen > ( R.Right - R.Left ) then begin if SysLocale.DefaultLCID <> $040D then S2 := Copy( S, 1, 2 ) else // Hebrew - Day name abbreviations handled differently begin if Length( S ) >= 5 then S2 := S[ 5 ] else S2 := S[ 1 ]; end; if Canvas.TextWidth( S2 ) > ( R.Right - R.Left ) then DrawString( Canvas, S2[ 1 ], R, dt_VCenter or dt_SingleLine or dt_Right or dt_NoClip ) else DrawString( Canvas, S2, R, dt_VCenter or dt_SingleLine or dt_Right or dt_NoClip ) end else DrawString( Canvas, S, R, dt_VCenter or dt_SingleLine or dt_Right or dt_NoClip ); OffsetRect( R, FCellSize.X, 0 ); end; Canvas.Font.Size := SaveFontSize; if ceWeekNumbers in FElements then begin if FThemeAware and ThemeServices.ThemesEnabled then Offset := 6 else Offset := 5; DrawHorizontalLine( Areas[ caWeekNumbers ].Right - Offset, Areas[ caDaysOfWeek ].Right, R.Bottom ); end else DrawHorizontalLine( Areas[ caDaysOfWeek ].Left, Areas[ caDaysOfWeek ].Right, R.Bottom ); end; // Draw Days DaysRect := Areas[ caDays ]; CMBoldDays := 0; // Current Month PMBoldDays := 0; // Previous Month NMBoldDays := 0; // Next Month DecodeDate( FViewDate, ViewYear, ViewMonth, Day ); GetBoldDays( ViewYear, ViewMonth, CMBoldDays ); if ceFillDays in FElements then begin DecodeDate( IncMonth( FViewDate, -1 ), Year, Month, Day ); GetBoldDays( Year, Month, PMBoldDays ); DecodeDate( IncMonth( FViewDate, 1 ), Year, Month, Day ); GetBoldDays( Year, Month, NMBoldDays ); end; if ceWeekNumbers in FElements then begin Canvas.Pen.Color := FCalendarColors.DaysOfWeek; if FThemeAware and ThemeServices.ThemesEnabled then Offset := 1 else Offset := 0; DrawVerticalLine( Areas[ caWeekNumbers ].Top - Offset, Areas[ caWeekNumbers ].Bottom + Offset, Areas[ caWeekNumbers ].Right - 5 ); end; R := Bounds( DaysRect.Left, DaysRect.Top - 1, FCellSize.X - 2, FCellSize.Y ); WR := Areas[ caWeekNumbers ]; Inc( WR.Top, 1 ); WR.Bottom := WR.Top + FCellSize.Y; Dec( WR.Right, 5 ); DrawDate := FFirstDateInGrid; for I := 0 to 5 do begin for J := 0 to 6 do begin DecodeDate( DrawDate, Year, Month, Day ); DayColor := Color; DayFontStyle := []; if ( Month = ViewMonth ) and ( Year = ViewYear ) then begin DayFontColor := FCalendarColors.Days; BoldDaysMask := CMBoldDays; end else begin DayFontColor := FCalendarColors.FillDays; if EncodeDate( Year, Month, 1 ) > EncodeDate( ViewYear, ViewMonth, 1 ) then BoldDaysMask := NMBoldDays else BoldDaysMask := PMBoldDays; end; if ( ( ceFillDays in FElements ) or ( Month = ViewMonth ) ) then begin // Determine Day Color CustomDayFormat := GetDayFormat( DrawDate, Year, Month, Day, DayColor, DayFontColor, DayFontStyle ); Canvas.Font.Color := DayFontColor; Canvas.Font.Style := DayFontStyle; Canvas.Brush.Color := DayColor; if ColorToRGB( DayColor ) <> ColorToRGB( Color ) then begin DayR := R; Inc( DayR.Right, 2 ); Canvas.FillRect( DayR ); end; if not CustomDayFormat then begin // if not using a CustomDayFormat, then go ahead and apply BoldDaysMask if ( BoldDaysMask and ( $1 shl ( Day - 1 ) ) ) = 0 then Canvas.Font.Style := Canvas.Font.Style - [ fsBold ] else Canvas.Font.Style := Canvas.Font.Style + [ fsBold ]; end; if DrawDate = Trunc( FDate ) then begin // Highlight selected Date SelRect := R; Inc( SelRect.Right, 2 ); Canvas.Font.Color := FCalendarColors.SelectedDateFore; Canvas.Brush.Color := FCalendarColors.SelectedDateBack; FillRect( Canvas.Handle, SelRect, Canvas.Brush.Handle ); if Focused then Canvas.DrawFocusRect( SelRect ); end; DrawString( Canvas, IntToStr( Day ), R, dt_VCenter or dt_SingleLine or dt_Right or dt_NoClip ); if DrawDate = Trunc( SysUtils.Date ) then begin // Highlight Today's date Canvas.Pen.Color := FCalendarColors.TodaysDateFrame; Canvas.Brush.Style := bsClear; Canvas.Rectangle( R.Left, R.Top, R.Right + 2, R.Bottom ); Canvas.Brush.Style := bsSolid; end; end; OffsetRect( R, FCellSize.X, 0 ); DrawDate := DrawDate + 1; end; if ceWeekNumbers in FElements then begin Canvas.Brush.Color := Color; Canvas.Font.Color := FCalendarColors.DaysOfWeek; if Assigned( FOnGetWeekNumber ) then begin WN := WeekOf( DrawDate - 6 ); FOnGetWeekNumber( Self, DrawDate, WN ); DrawStringCentered( Canvas, IntToStr( WN ), WR ); end else DrawStringCentered( Canvas, IntToStr( WeekOf( DrawDate - 6 ) ), WR ); OffsetRect( WR, 0, FCellSize.Y ); end; OffsetRect( R, DaysRect.Left - R.Left, FCellSize.Y ); end; if ButtonsVisible then begin if ceWeekNumbers in FElements then begin if FThemeAware and ThemeServices.ThemesEnabled then Offset := 6 else Offset := 5; DrawHorizontalLine( Areas[ caWeekNumbers ].Right - Offset, DaysRect.Right, DaysRect.Bottom - 1 ); end else DrawHorizontalLine( DaysRect.Left, DaysRect.Right, DaysRect.Bottom - 1 ); end; end; end; {= TRzCalendar.Paint =}
修改後需要重新編譯,然後將編譯後的dcu拷貝至delphi的引用目錄下即可。但是,在編譯的時候又遇到麻煩了,編譯不過去,老是提示RzBorder.pas有問題,最後也改了這個檔案,主要更改的地方有兩個地方:
1、TRzLEDValidChars = Chr( 32 )..Chr( 126 ); //原來是255,修改為126,其實已經夠用了
2、DotMasks: TRzLEDCharacters = .......//這個宣告也改了,將( {~} Col0: $40; Col1: $80; Col2: $40; Col3: $20; Col4: $40 )後面的都截掉了,這樣就可以編譯通過,目前還沒有發現有啥副作用。