//コンポーネントを交換する関数
//usesにTypInfoの追加が必要
function ChangeComponent(Original: TComponent; NewClass: TComponentClass): TComponent;
var
New: TComponent;
Stream: TStream;
Methods: array of TMethod;
aPPropInfo: array of PPropInfo;
MethodCount, i: Integer;
begin
SetLength(aPPropInfo, 16379);
MethodCount := GetPropList(Original.ClassInfo, [tkMethod], @aPPropInfo[0]);
SetLength(Methods, MethodCount);
for i := 0 to MethodCount - 1 do
Methods[i] := GetMethodProp(Original, aPPropInfo[i]);
Stream := TMemoryStream.Create;
try
Stream.WriteComponent(Original);
New := NewClass.Create(Original.Owner);
if New is TControl then
TControl(New).Parent := TControl(Original).Parent;
Original.Free;
Stream.Position := 0;
Stream.ReadComponent(New);
finally
Stream.free
end;
for i := 0 to MethodCount - 1 do
SetMethodProp(New, aPPropInfo[i], Methods[i]);
Result := New;
end;
この関数を、FormCreate時に呼び出して、実行。
procedure TFormCollaboration.FormCreate(Sender: TObject);
begin
//コンポーネントを交換する関数を実行
StringGrid1:= TStringGrid(ChangeComponent(StringGrid1, TplDropStringGrid));
end;
ここまでが準備で、縦のアライメントの設定は、次のたった1行(赤字)を追加するのみ!
procedure TFormCollaboration.StringGrid1GetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: string);
begin
//縦のアライメントを設定
TplDropStringGrid(StringGrid1).EditVertAlignment := vaCenter;
//IMEの制御
with TEdit(_TGrid(Sender).InplaceEditor) do
begin
//ImeMode := imClose; //日本語入力OFF-> ×
ImeMode := imDisable; //日本語入力OFFは imDisable
end;
//現在Activeな行番号を取得
intStringGrid1ActiveRow:=ARow;
end;
procedure TFormCollaboration.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
LDelta:Integer;
LWinCtrl:TWinControl;
LCurPos:TPoint;
//スクロール量の調整(SA:Scroll Amount)
intSA:integer;
begin
//マウスカーソルが TScrollBox の領域内にある時だけスクロールを可能にする
//(解答欄画像を表示しているTImageはTScrollBoxの上に配置)
LCurPos := ScrollBox1.Parent.ScreenToClient(MousePos);
if PtInRect(ScrollBox1.BoundsRect, LCurPos) then
begin
//スクロール量の調整
if not TryStrToInt(調整値1-10を設定するComboBoxの値, intSA) then
begin
intSA:=1;
end;
//心配なので、念のために設定その1
if 調整値1-10を設定するComboBoxの値 ='0' then
begin
intSA:=1;
end;
//心配なので、念のために設定その2
if StrToInt(調整値1-10を設定するComboBoxの値) < 0 then
begin
intSA:=1;
end;
//大きい数値を選ぶとスクロール量も大きくなるように設定
intSA:=11-intSA;
LDelta := WheelDelta div intSA;
if ssCtrl in Shift then
begin
ScrollBox1.HorzScrollBar.Position :=
ScrollBox1.HorzScrollBar.Position - LDelta;
end else begin
ScrollBox1.VertScrollBar.Position :=
ScrollBox1.VertScrollBar.Position - LDelta;
//StringGridも連動してスクロールさせる
if LDelta > 0 then
begin
StringGrid1.Perform(WM_VSCROLL, SB_LINEUP, 0);
end else begin
StringGrid1.Perform(WM_VSCROLL, SB_LINEDOWN, 0);
end;
end;
end else begin
//マウス直下のコントロールを取得
LWinCtrl:=FindVCLWindow(MousePos);
//TStringGridの場合
if LWinCtrl is TStringGrid then
begin
if WheelDelta > 0 then
begin
LWinCtrl.Perform(WM_VSCROLL, SB_LINEUP, 0);
end else begin
LWinCtrl.Perform(WM_VSCROLL, SB_LINEDOWN, 0);
end;
end;
end;
//この1行を忘れないこと!
Handled:=True;
end;
//正負をチェック
if StrToInt(StringGrid1.Cells[ACol,ARow])< 0 then
begin
StringGrid1.Canvas.Font.Color := clRed;
end else begin
StringGrid1.Canvas.Font.Color := clBlack;
end;
//Gridコントロールへの入力値がない場合は「何もしない」
procedure TFormCollaboration.StringGrid1DrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
var
・・・ 必要な変数を宣言 ・・・
//例
intValue : integer;
begin
// 以下、実際のプログラムコードから必要な部分のみ抜粋
if StringGrid1.Cells[ACol,ARow]<>'' then
begin
// 誤入力'00'があれば'0'に変換
if StringGrid1.Cells[ACol,ARow]='00' then
begin
StringGrid1.Cells[ACol,ARow]:='0';
end;
// 入力文字数が3文字以上なら'0'に変換
if Length(WideString(StringGrid1.Cells[ACol,ARow])) > 2 then
begin
StringGrid1.Cells[ACol,ARow]:='0';
end;
// 入力値が「数値」に変換できなかった場合はすべて'0'に変換
if not TryStrToInt(StringGrid1.Cells[ACol,ARow], intValue) then
begin
StringGrid1.Cells[ACol,ARow]:='0';
end;
//背景色を白に設定
StringGrid1.Canvas.Brush.Color:=clWhite;
//正負をチェック
if StrToInt(StringGrid1.Cells[ACol,ARow])< 0 then
begin
StringGrid1.Canvas.Font.Color:=clRed;
end else begin
StringGrid1.Canvas.Font.Color:=clBlack;
end;
//セルを塗りつぶす
StringGrid1.Canvas.FillRect(Rect);
//テキストを表示(中央寄せ)
DrawText(StringGrid1.Canvas.Handle,
PChar(StringGrid1.Cells[ACol,ARow]),
//[+1]は数値描画位置の調整のため
Length(StringGrid1.Cells[ACol,ARow])+1,Rect,
DT_CENTER or DT_VCENTER or DT_SINGLELINE);
end;
//Cellの値が0ではなかった場合の処理
if not (StringGrid1.Cells[ACol,ARow]='0') then
begin
//Cellの値が正だった場合(完全正答〇の処理)
if StrToInt(StringGrid1.Cells[ACol,ARow]) > 0 then
begin
//imgAnswerは答案画像を表示するTImage
//Windows APIのSetBkMode関数でTRANSPARENTを指定
SetBkMode(imgAnswer.Canvas.Handle, TRANSPARENT);
imgAnswer.Canvas.Font.Color := clRed;
imgAnswer.Canvas.Font.Size := StrToInt(FontSize指定用ComboBox.Text);
case RadioGroup4.ItemIndex of
0:begin
//cmbX, cmbYは表示位置調節用の値を入力するComboBox
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), '○');
end;
1:begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), StringGrid1.Cells[ACol,ARow]);
end;
2:begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), '○'+StringGrid1.Cells[ACol,ARow]);
end;
end;
end else begin
//Cellの値が負だった場合(△)-> この部分を新規に追加
if StrToInt(StringGrid1.Cells[ACol,ARow]) < 0 then
begin
//Windows APIのSetBkMode関数でTRANSPARENTを指定
SetBkMode(imgAnswer.Canvas.Handle, TRANSPARENT);
imgAnswer.Canvas.Font.Color := clRed;
imgAnswer.Canvas.Font.Size := StrToInt(FontSize指定用ComboBox.Text);
case RadioGroup4.ItemIndex of
0:begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), '△');
end;
1:begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text),
IntToStr(Abs(StrToInt(StringGrid1.Cells[ACol,ARow]))));
end;
2:begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), '△'+
IntToStr(Abs(StrToInt(StringGrid1.Cells[ACol,ARow]))));
end;
end;
end;
end;
end else begin
//不正解の場合の処理(×)
//Windows APIのSetBkMode関数でTRANSPARENTを指定
SetBkMode(imgAnswer.Canvas.Handle, TRANSPARENT);
imgAnswer.Canvas.Font.Color := clRed;
imgAnswer.Canvas.Font.Size := StrToInt(FontSize指定用ComboBox.Text);
case RadioGroup4.ItemIndex of
0:begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), '×');
end;
1:begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), StringGrid1.Cells[ACol,ARow]);
end;
2:begin
//chkZeroはCaption「得点0は表示しない」のCheckBox
if not chkZero.Checked then
begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), '×'+StringGrid1.Cells[ACol,ARow]);
end else begin
imgAnswer.Canvas.TextOut(DestRect.Left+StrToInt(cmbX.Text),
DestRect.Top+StrToInt(cmbY.Text), '×');
end;
end;
end;
end;
end;
var
i,j,k : integer;
begin
//合計点を入れる変数kを初期化
k := 0;
//合計点を計算
for i := 1 to StringGrid1.RowCount-1 do
begin
for j := 1 to StrToInt(解答欄数.Text) do
begin
if StringGrid1.Cells[j,i] <> '' then
begin
//△に非対応
//k := K + StrToInt(StringGrid1.Cells[j,i]);
//△は負の数で入力しているから絶対値で計算
k := K + Abs(StrToInt(StringGrid1.Cells[j,i]));
end;
end;
//合計点を保存(StringGrid.Cells[列, 行])
StringGrid1.Cells[StrToInt(解答欄数.Text)+1, i] := IntToStr(k);
//合計点を初期化
k := 0;
end;
end;
Windows10になって、いちばん困ったのはプリンタの管理方法の変化だった。デフォルト設定で、最後に使ったプリンタが通常使うプリンタと見なされるようになってから、職場のあちこちで「印刷ができない!」という声が上がることが多くなった。駆け付けてみると、出力先プリンタはいつも「Microsoft Print to PDF」みたいな・・・。