unit common; interface uses ActnList, Classes, ExtCtrls, Forms, StdCtrls, SysUtils, Graphics, Controls; //ショートカット function G_fnsCommandDescriptionGet(AAction: TAction): String; function G_fnsCommandHintGet(AAction: TAction): String; //アクションリストのカテゴリ抽出 procedure G_CategoryListGet(AItems: TStrings); type EFormatStringError = class(Exception) constructor Create(sString: String); end; EFormatTypeError = class(Exception) public constructor Create(sType: String; slList: array of String); end; //フィールド取り出し function G_fnsFormatField(var sSrc: String; out sSep: String; slList: array of String): String; overload; function G_fnsFormatField(var sSrc: String; slList: array of String): String; overload; function G_fnsFormatField(var sSrc: String): String; overload; //--- 高DPI環境への対応 -------------------------------------------------------- function G_fniHighDPIControlHeightGet(AControl: TControl; iHeight: Integer = 0): Integer; //procedure G_HighDPIControlHeightSet(AControl: TControl; iHeight: Integer = 0); procedure G_ControlWidthSet(AControl: TControl); //コントロールのTop調整 procedure G_ControlTopSet(AControl: TControl); overload; procedure G_ControlTopSet(A1stControl: TControl; AControls: array of TControl); overload; procedure G_ControlTopSet(AControls: array of TControl); overload; //閉じるボタンのLeft調整 procedure G_CloseButtonLeftSet(AButton: TButton); procedure G_ButtonWidthSet(AButton: TButton); procedure G_ControlLeftSet(AControl: TControl); overload; procedure G_ControlLeftSet(A1stControl: TControl; AControls: array of TControl); overload; procedure G_ControlLeftSet(AControls: array of TControl); overload; //下部コマンドボタン用Panelの高さ調整 procedure G_PanelCmdHieghtSet(APanel: TPanel); //コマンドヒント表示用のグループボックスの高さ調整 procedure G_HintBoxHeightSet(AGroupBox: TGroupBox); //コマンドボタンの高さ調整 procedure G_ButtonHeightSet(AForm: TForm); const G_ciTEXT_MARGIN = 2; G_ciCONTROL_MARGIN = 8; //============================================================================== implementation uses Menus, Grids, CheckLst, ComCtrls, main, lang, highDPIUnit, general; function G_fniHighDPIControlHeightGet(AControl: TControl; iHeight: Integer = 0): Integer; function _CalcHeight(AFont: TFont; iHeight: Integer; fMagni: Extended): Integer; begin Result := gfniMax([Trunc(Abs(AFont.Height) * fMagni), iHeight]); end; function _CalcControlHeight(AFont: TFont; iHeight: Integer = 0): Integer; begin Result := _CalcHeight(AFont, iHeight, gcfHIGHDPI_CONTROLSPACE); end; function _CalcTextHeight(AFont: TFont; iHeight: Integer = 0): Integer; begin Result := _CalcHeight(AFont, iHeight, gcfHIGHDPI_FONTSPACE); end; begin if (AControl is TComboBox) then begin Result := _CalcTextHeight(TComboBox(AControl).Font, iHeight); end else if (AControl is TListBox) then begin Result := _CalcTextHeight(TListBox(AControl).Font, iHeight); end else if (AControl is TCheckListBox) then begin Result := _CalcTextHeight(TCheckListBox(AControl).Font, iHeight); end else if (AControl is TStringGrid) then begin Result := _CalcTextHeight(TStringGrid(AControl).Font, iHeight); end else if (AControl is TStatusBar) then begin Result := _CalcControlHeight(TStatusBar(AControl).Font, iHeight); end else if (AControl is TGroupBox) then begin Result := Trunc(Abs(TGroupBox(AControl).Font.Height) * 3); end else if (AControl is TLabel) then begin Result := _CalcControlHeight(TLabel(AControl).Font); end else if (AControl is TButton) then begin Result := _CalcControlHeight(TButton(AControl).Font); end else begin Result := AControl.Height; end; end; procedure G_HighDPIControlHeightSet(AControl: TControl; iHeight: Integer = 0); begin if (AControl is TComboBox) then begin TComboBox(AControl).ItemHeight := G_fniHighDPIControlHeightGet(AControl, iHeight); end else if (AControl is TListBox) then begin TListBox(AControl).ItemHeight := G_fniHighDPIControlHeightGet(AControl, iHeight); end else if (AControl is TCheckListBox) then begin TCheckListBox(AControl).ItemHeight := G_fniHighDPIControlHeightGet(AControl, iHeight); end else if (AControl is TStringGrid) then begin TStringGrid(AControl).DefaultRowHeight := G_fniHighDPIControlHeightGet(AControl, iHeight); end else if (AControl is TStatusBar) then begin TStatusBar(AControl).Height := G_fniHighDPIControlHeightGet(AControl, iHeight); end else if (AControl is TGroupBox) then begin TGroupBox(AControl).Height := G_fniHighDPIControlHeightGet(AControl); end else if (AControl is TLabel) then begin TLabel(AControl).Height := G_fniHighDPIControlHeightGet(AControl); end else if (AControl is TButton) then begin TButton(AControl).Height := G_fniHighDPIControlHeightGet(AControl); end; end; procedure G_ControlWidthSet(AControl: TControl); begin AControl.Width := AControl.Parent.ClientWidth - (G_ciCONTROL_MARGIN * 2); end; procedure G_ControlTopSet(AControls: array of TControl); var i: Integer; l_Control : TControl; begin //一番目のコントロールのTopはいじらない。 for i := 1 to High(AControls) do begin l_Control := AControls[i -1]; if (l_Control is TLabel) then begin AControls[i].Top := l_Control.BoundsRect.Bottom + gciHIGHDPI_LABELMARGIN; end else begin AControls[i].Top := l_Control.BoundsRect.Bottom + G_ciCONTROL_MARGIN; end; end; end; procedure G_ControlTopSet(AControl: TControl); begin AControl.Top := G_ciCONTROL_MARGIN; end; procedure G_ControlTopSet(A1stControl: TControl; AControls: array of TControl); var i : Integer; l_Control : TControl; begin A1stControl.Top := G_ciCONTROL_MARGIN; AControls[0].Top := A1stControl.BoundsRect.Bottom + G_ciCONTROL_MARGIN; for i := 1 to High(AControls) do begin l_Control := AControls[i -1]; AControls[i].Top := l_Control.BoundsRect.Bottom + G_ciCONTROL_MARGIN; end; end; procedure G_CloseButtonLeftSet(AButton: TButton); begin AButton.Left := AButton.Parent.ClientWidth - AButton.Width - G_ciCONTROL_MARGIN; end; procedure G_ControlLeftSet(AControl: TControl); begin AControl.Left := G_ciCONTROL_MARGIN; end; procedure G_ControlLeftSet(A1stControl: TControl; AControls: array of TControl); overload; var i : Integer; l_Control : TControl; begin A1stControl.Left := G_ciCONTROL_MARGIN; AControls[0].Left := A1stControl.BoundsRect.Right + G_ciCONTROL_MARGIN; for i := 1 to High(AControls) do begin l_Control := AControls[i -1]; AControls[i].Left := l_Control.BoundsRect.Right + G_ciCONTROL_MARGIN; end; end; procedure G_ControlLeftSet(AControls: array of TControl); var i : Integer; l_Control : TControl; begin for i := 1 to High(AControls) do begin l_Control := AControls[i -1]; AControls[i].Left := l_Control.BoundsRect.Right + G_ciCONTROL_MARGIN; end; end; procedure G_PanelCmdHieghtSet(APanel: TPanel); var i: Integer; l_Button : TButton; begin if (APanel = nil) then Exit; for i := 0 to APanel.ControlCount -1 do begin if (APanel.Controls[i] is TButton) then begin l_Button := TButton(APanel.Controls[i]); APanel.Height := l_Button.Height + (G_ciCONTROL_MARGIN * 2); end; end; end; procedure G_ButtonHeightSet(AForm: TForm); var i: Integer; begin if (AForm = nil) then Exit; for i := 0 to AForm.ControlCount -1 do begin if (AForm.Controls[i] is TButton) then begin gpcButtonHeightSet(TButton(AForm.Controls[i])); end; end; end; procedure G_ButtonWidthSet(AButton: TButton); begin AButton.Width := gfniCanvasTextWidthGet(AButton.Font, AButton.Caption); end; procedure G_HintBoxHeightSet(AGroupBox: TGroupBox); begin AGroupBox.Height := G_fniHighDPIControlHeightGet(AGroupBox); end; constructor EFormatStringError.Create(sString: String); begin inherited Create(Format(G_csGENERAL_ERRFMTSTR, [sString])); // 'コピーの形式指定子にエラーがあります'#13 // + '形式指定子が正しく終了していません'#13 // + sString end; constructor EFormatTypeError.Create(sType: String; slList: array of String); var ls_List: String; i: Integer; begin ls_List := ''; for i := 0 to High(slList) do begin ls_List := ls_List + ' ' + slList[i]; end; inherited Create(Format(G_csGENERAL_ERRFMTTYPE, [ls_List, sType])); // 'コピーの形式指定子にエラーがあります'#13 // + '指定できる指定子は'#13 // + ls_List // + #13'ですが ' + sType + ' が指定されています' end; //------------------------------------------------------------------------------ //ショートカット function G_fnsCommandDescriptionGet(AAction: TAction): String; begin if (AAction = nil) then begin Result := ''; end else if (AAction.Category = G_MainForm.actSpc.Category) then begin Result := G_MainForm.actSpc.Caption; end else begin Result := Format('%s/%s', [AAction.Category, StripHotKey(AAction.Caption)]); end; end; function G_fnsCommandHintGet(AAction: TAction): String; begin if (AAction = nil) then begin Result := ''; end else if (AAction.Category = G_MainForm.actSpc.Category) then begin Result := G_MainForm.actSpc.Caption; end else if (AAction.Hint = '') then begin Result := G_fnsCommandDescriptionGet(AAction); end else begin Result := AAction.Hint; end; end; //アクションリストのカテゴリ抽出 procedure G_CategoryListGet(AItems: TStrings); var i : Integer; ls_Category : String; l_Action : TAction; begin ls_Category := ''; for i := 0 to G_ActionList.ActionCount -1 do begin l_Action := TAction(G_ActionList.Actions[i]); if (l_Action.Category <> ls_Category) then begin AItems.Add(ls_Category); ls_Category := l_Action.Category; end; end; end; //フィールド取り出し ----------------------------------------------------------- function G_fnsFormatField(var sSrc: String; out sSep: String; slList: array of String): String; //フォーマット形式文字列を区切りとして分割して返す。 //sSrcは分割された残りの文字列。 var ls_WSrc, ls_WCSrc, ls_WSep, ls_WResult: WideString; i, li_Len: Integer; begin ls_WSrc := WideString(sSrc); ls_WCSrc := WideLowerCase(ls_WSrc); li_Len := Length(ls_WSrc); ls_WSep := ''; ls_WResult := ''; i := 1; while (i <= li_Len) do begin if (ls_WCSrc[i] = '%') and (i < li_Len) then begin if (ls_WCSrc[i+1] = '%') then begin //ls_WCSrc[i]が%であれば次を確認し、それも%であれば処理を一つ飛ばす。 //%はエスケープされるため //%%は%として処理する ls_WResult := ls_WResult + ls_WSrc[i]; Inc(i); end else begin //%%ではなかったので形式文字列である可能性あり ls_WSep := '%'; Inc(i); while (i <= li_Len) do begin if (Pos(ls_WCSrc[i], '-:*.0123456789') > 0)then begin //形式文字列の可能性ありだが確定ではない ls_WSep := ls_WSep + ls_WCSrc[i]; end else if (Pos(ls_WCSrc[i], 'duefgnmpsx') > 0) then begin //形式文字列だった sSep := String(ls_WSep + ls_WSrc[i]); //myDebug.gpcDebug(High(slList)); if (High(slList) = -1) or (gfnbIsIncludeList(sSep, slList)) then begin Result := String(ls_WResult); sSrc := String(Copy(ls_WSrc, i+1, MAXINT)); end else begin Result := ''; sSep := ''; raise EFormatTypeError.Create(String(ls_WSep + ls_WSrc[i]), slList); end; Exit; end else begin //形式文字列ではなかった //イレギュラーな形式 Result := ''; sSep := ''; raise EFormatStringError.Create(ls_WSep); { ls_WResult := ls_WResult + ls_WSep; ls_WSep := ''; if (ls_WCSrc[i] = '%') then begin //%の判定を外側のループで判定させるためDec(i)とする Dec(i); end else begin ls_WResult := ls_WResult + ls_WSrc[i]; end; Break; } end; Inc(i); end; end; end else begin ls_WResult := ls_WResult + ls_WSrc[i]; end; Inc(i); end; //ここにくるということはセパレータがなかったということ Result := String(ls_WResult + ls_WSep); sSrc := ''; sSep := ''; end; function G_fnsFormatField(var sSrc: String; slList: array of String): String; overload; var ls_Sep: String; begin Result := G_fnsFormatField(sSrc, ls_Sep, slList); end; function G_fnsFormatField(var sSrc: String): String; overload; var ls_Sep: String; begin Result := G_fnsFormatField(sSrc, ls_Sep, []); end; end.