Delphiプログラム解読不可!StringGridのセルを右寄せにする方法とは?

このQ&Aのポイント
  • このDelphiプログラムでは、StringGridの1列目と2列目の各セルの内容を右寄せにするための方法が紹介されています。
  • プログラム内の 'Rect.Top:=Rect.Top+2;' という行について、なぜ+2なのかという疑問があります。
  • 'gdFixed'や'FillRect'、'DT_RIGHT'などの用語についても理解が必要です。解説お願いします!
回答を見る
  • ベストアンサー

Delphiに関して  「このプログラム解読できません!」

こんにちは。このプログラムが解読不可です。StringGridの1列目と2列目の各セルの内容を右寄せにする ということで、実行させると確かにそうなるのですが、どういう構造かいまいち分かりません。特に 'Rect.Top:=Rect.Top+2;' のところなんて"なんで+2なの~?"ってホントに謎です。gdFixedとかFillRectとかヘルプに書いてあることとなんか違う気がして....DT_RIGHTもわかりません。 このプログラムの解説お願いします! procedure TForm1.StringGrid1DrawCell(Sender:TObject;ACol,ARow:Integer;Rect: TRect; State: TGridDrawState); begin If Not (gdFixed In State) And (ACol In [1,2]) Then Begin StringGrid1.Canvas.FillRect(Rect); Rect.Top := Rect.Top + 2; If (ACol = 1)or(ACol = 2) Then DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells                 [ACol,ARow]),Lengthend(StringGrid1.Cells                [ACol,ARow]),Rect,DT_RIGHT) end; end;

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

ざっと見るに・・・ > Rect.Top:=Rect.Top + 2; この前にStringGridのCanvasに上下左右のポイント(表示位置)を設定しているのでしょう。 そこに、更に上書きでTopの位置を今の位置よりも「2」ポイント上にしなさいといっています。 > If Not (gdFixed In State) And (ACol In [1,2]) Then Stateのなかに「gdFixed」が含まれていないで、列が「1か2」以外なら実行しなさい。 > FillRect 塗りつぶすという命令です。 > DT_RIGHT WindowsAPIの「DrawText」の中の一部です。 「Aligns text to the right.」とあります。「Align」を右寄せにしなさいということでしょうね。 こんなもんでいかがでしょう。

s97229
質問者

お礼

ありがとうございました!助かりました!教えていただたことをもとに、全体の解読を頑張ってみます!今年、社会人一年生で、今プログラミング研修中なのですが、人のプログラムを理解するのはむずかし~!頑張ります。ありがとうございました。

関連するQ&A

  • DelphiのTreeViewでの+ボタンの出し方

    WindowsXP、Delphi2009で開発しています。 TTreeViewのAdvancedCustomDrawItemで下記の様に動的にノードの描画を行っていますが、ノードを展開・折りたたみする際に使う+ボタンが表示できなくて困っています。 +ボタンを表示させる方法が分かる方、ご教示願います。 ------------------------------------------------------------ procedure TForm3.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages, DefaultDraw: Boolean); var Rect :TRect; begin defaultdraw := false; Rect := Node.DisplayRect(True); if Node.Selected = true then begin Sender.Canvas.Font.Color := clWhite; end else begin if Copy(Node.Text,pos('\',Node.Text) + 1, length(Node.Text)) = 'False' then begin Sender.Canvas.Font.Color := clWindowText; end else begin Sender.Canvas.Font.Color := clRed; end; end; Sender.Canvas.TextOut(Rect.Left,Rect.Top,Copy(Node.Text,1,pos(',',Node.Text) - 1)); end; ------------------------------------------------------------

  • StringGrid1で画面におさまりきらない行をForm2から遠隔スクロールするには?

    Form1のStringGrid1で、画面におさまりきらない行を、Form2から次のようなやり方で遠隔スクロールさせたいのですがうまくいきません。目的の矩形 StringGrid1.Cells[ col, row ] をちゃんとselect しているはずなんですが、その行の位置が画面表示行よりも下方にあるために、それが見えないのです。御教示いただければありがたいのですが。 procedure TForm2.Next1Click(Sender: TObject); var R : TGridRect; begin with R do begin Left := Form1.StringGrid1.Col; Top :=Form1.StringGrid1.Row+1; Right := Form1.StringGrid1.Col; Bottom := Form1.StringGrid1.Row+1; end; Form1.StringGrid1.Selection := R; end;

  • Delphiプログラミングについて

    この内容ではいけないのでしょか? また、代わりの方法なども教えていただけると嬉しいです ボタン ラベル がフォーム1の上に1つずつあるだけです お願いいたします unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Label1: TLabel; Button1: TButton; procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; i:integer; implementation {$R *.dfm} procedure hyouji; begin repeat form1.label1.caption:= 'strike'; until i = 10; end; procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (KEY = VK_RIGHT) then i:=i+1; end; procedure TForm1.Button1Click(Sender: TObject); begin hyouji end; end.

  • 直線検出のハフ変換プログラム(delphi)

    ただいまdelphiで直線検出のハフ変換のプログラムを書いているのですが、コンパイルし、実行しようとするとスタックオーバーフローになってしまいます。 おそらく2次元配列のcounterの部分だと思うのですが、どなたか回避の仕方お分かりになるでしょうか? ご存じの方いらっしゃいましたら教えて下さい。 下記にハフ変換の部分のコードを載せます。 他にも何か気付いた点ありましたらご指摘お願いいたします。 ○直線検出のハフ変換○ var i, j, k, n: Integer; rx, ry: Integer; clr: tcolor; R: longint; counter_max: Integer; THETA_RESOLUTION, RHO_RESOLUTION, LNUMBER_MAX: Integer; pai: Double; theta, rho: Integer; theta_max, rho_max, count: Integer; theta_cut, rho_cut: Integer; counter:array[0..1023,0..1999] of Integer; //直線検出のためのカウンタ sn:array[0..1023] of Double; //sin cs:array[0..1023] of Double; //cos begin THETA_RESOLUTION:=1024; //thetaの範囲は0から1023まで RHO_RESOLUTION:=2000; //rhoの範囲は-1000から999まで LNUMBER_MAX:=15; //検索する電線の数は15まで pai:=PI / THETA_RESOLUTION; //π÷THETA_RESOLUTION for i:=0 to 1023 do //sinとcosのテーブルを用意 begin sn[i]:=Sin(pai*i); cs[i]:=Cos(pai*i); end; //ハフ変換の実行// for rx:=0 to 639 do begin for ry:=0 to 479 do begin clr:=image1.Canvas.Pixels[rx,ry]; R:=colortorgb(clr); if(getrvalue(R)=0)and(getgvalue(R)=0)and(getbvalue(R)=0) then //黒である for theta:=0 to 1023 do begin rho:=Trunc(rx*cs[theta]+ry*sn[theta]+0.5); counter[theta,rho+1000]:=counter[theta,rho+1000]+1; end; end; end; //ハフ逆変換の実行// for n:=0 to 14 do begin //counterが最大になるtheta_maxとrho_maxを求める// counter_max:=0; for theta:=0 to 1023 do begin for rho:=-RHO_RESOLUTION div 2 to RHO_RESOLUTION div 2-1 do begin if(counter[theta,rho+RHO_RESOLUTION div 2] > counter_max) then begin counter_max:=counter[theta,rho+RHO_RESOLUTION div 2]; theta_max:=theta; rho_max:=rho; count:=counter_max; end; end; end; //counter[theta_max,rho_max]の近傍を0にする// for i:=-20 to 20 do begin for j:=-10 to 10 do begin theta_cut:=theta_max+i; rho_cut:=rho_max+j; if(theta_cut < 0) then begin theta_cut:=theta_cut+THETA_RESOLUTION; rho_cut:=-rho_cut; end else if(theta_cut > THETA_RESOLUTION-1) then begin theta_cut:=theta_cut-THETA_RESOLUTION; rho_cut:=-rho_cut; end; counter[theta_cut,rho_cut+RHO_RESOLUTION div 2]:=0; //削除する end; end; //ハフ逆変換した結果の表示// if(theta_max<>0) then //垂線の線を描く begin for rx:=0 to 639 do begin ry:=Trunc((rho_max-rx*cs[theta_max])/sn[theta_max]+0.5); if(ry>=480)or(ry<0) then continue; image1.Canvas.Pixels[rx,ry]:=RGB(255,0,0); end; end; if(theta_max<>THETA_RESOLUTION div 2) then //水平の線を描く begin for ry:=0 to 479 do begin rx:=Trunc((rho_max-ry*sn[theta_max])/cs[theta_max]+0.5); if(rx>=640)or(rx<0) then continue; image1.Canvas.Pixels[rx,ry]:=RGB(255,0,0); end; end; //直線を形成するピクセルが60個未満になったら表示しない// if count<60 then break; end; end;

  • Delphi for文

    これって、Delphiのバグですか?特性ですか? procedure TForm1.Button1Click(Sender: TObject); begin test(); end; //-------------------------- procedure TForm1.test(); var k,x:integer; begin paintbox1.Canvas.pen.Color:=clBlack ; x:=0; for k:=1 to 3 do begin paintbox1.Canvas.moveto(x,0); paintbox1.Canvas.lineto(x,paintbox1.Height); x:=x+2; end; end; forループ内にブレークポイントを付けて「k」の値の変化を見ると、3,2,1と逆順になります。 「x:=x+2」を「x:=x+k」に変更すると、1,2,3と普通の順になります。 なぜ、こうなるのか? 対処法はありますか? Delphi Ver6・ターボDelphi どちらも同じ状況です。

  • Delphi6 ループ中にキー入力

    Delphi 6 です。 for next などのループの中で、stringgridのセルをEnterキーで選択させたい時、選択されるまで(キーが押されるまで)処理を進めたくない方法は、どうするんでしょうか? flg:=false; for i:=1 to 100 do begin ~諸々の処理で flg:=true; ~ if flg=true then x[i]:= stringgridの選択されたRow番号(はじめからフォーカスされている番号でなく) ~諸々の処理で flg:=false; ~ end;

  • StringGridの中身をCSV形式で保存するには、保存の際に、ファイル拡張子を自動で「.csv」を付与するには?

    こんにちは。 StringGridの中身をCSVデータとして保存したいのですが、 その際に、『自分の好きな名前』で『デスクトップ』に保存できるようにしたいと考えています。 ソース1では、CSV形式での保存は行えるのですが、 名前をつけるやり方とデスクトップの指定方法が分かりません。 opendialog,savedialogを使うと思うのですが、 上手く組み合わせることが出来ずに困っています。 ソース2では、理想どおりの結果を出力できるはずなんですが、 実行すると空の結果が出力されます。どこが間違っているか分からず、困り果てています。 ・間違っている部分がどこか? ・保存する際に自動で端子に.csvを付与するにはどうすれば良いか? アドバイス頂けると助かります。 宜しくお願いしします。 -----------ソース1:------------------------------------------ procedure TForm2.GridSaveCSV(SGrid:TStringGrid; fName: String); var stList :TStringList; ARow :Integer; begin stList:=TStringList.Create; try for ARow:=0 to SGrid.RowCount-1 do stList.Add(SGrid.Rows[ARow].CommaText); stList.SaveToFile(fName); finally stList.Free; end; end; //CSVFileからStringGridへ読込み1 procedure TForm2.GridLoadCSV(SGrid:TStringGrid; fName:string); var stList: TStringList; ARow: Integer; begin stList:=TStringList.Create; try stList.LoadFromFile(fName); SGrid.RowCount:= stList.Count; for ARow:=0 to stList.Count-1 do SGrid.Rows[ARow].CommaText:= stList[ARow]; finally stList.Free; end; end; procedure TForm2.Button3Click(Sender: TObject); var fName: String; begin fName := 'csvtest.csv'; GridSaveCSV(StringGrid1,fName); end; -------------------------------------------------------------- -----------ソース2:------------------------------------------ procedure TForm2.Button8Click(Sender: TObject); var F : TextFile; Str : String; CellA,CellB,CellC,CellD,CellE : String; RowCNT : Integer; begin if not SaveDialog1.Execute then exit; if FileExists(SaveDialog1.FileName) then //↑ここのFileNameの使い方が良く分かりません>< //保存するときに、自動で.csvが付与されるようにしたいと思っています。 if Application.MessageBox('上書きしますか','注意',MB_YESNO ) = 7 then exit; //_ AssignFile(F,SaveDialog1.FileName); Rewrite(F); RowCNT := 0; try while not (StringGrid1.Cells[0,RowCnt] = '') do begin CellA := StringGrid1.Cells[0,RowCnt]; CellB := StringGrid1.Cells[1,RowCnt]; CellC := StringGrid1.Cells[2,RowCnt]; CellD := StringGrid1.Cells[3,RowCnt]; CellE := StringGrid1.Cells[4,RowCnt]; Str := Format('%s,%s,%s,%s,%s'[CellA,CellB,CellC,CellD,CellE]); // ↑この辺りが怪しいと思っています。 WriteLn (F,Str); Inc(RowCNT); end; finally CloseFile(F); end; end;

  • エクセルVBAで、文字列の検索方法について

    先日、こちらで教えていただいたVBAがあります。 E列のセルの文字列の末尾が「計」のものを検索し、その行に色をつけるものです。 Sub iroiro() Dim x, y x = 1 Do If Right(Cells(x, 5), 1) = "計" Then For i = 2 To 5 Cells(x, i).Interior.ColorIndex = 3 Next End If x = x + 1 Loop Until Right(Cells(x, 5), 1) = "" End Sub これはばっちりで、助かっているのですが、今度は末尾ではなく、文字列中に「営業」という文字があるのを検索し、色をつけたいのです。 If Right(Cells(x, 5), 1) = "計" Thenを どう変えればいいのでしょうか?

  • 【Excelマクロ】もっと頭の良い書き方って無いかな?

    5行空白列があったらそこで処理を終わりたいんですが、もっといい書き方はないでしょうか? 下記が私の考えた頭の悪いやり方です。 Sub macro() Dim i As Integer For i = 1 To 1000 If Cells(i, 1) = "" Then  If Cells(i + 1, 1) = "" Then   If Cells(i + 2, 1) = "" Then    If Cells(i + 3, 1) = "" Then     If Cells(i + 4, 1) = "" Then      If Cells(i + 5, 1) = "" Then       MsgBox (i - 1 & "行目で終わりです")       Exit For      End If     End If    End If   End If  End If End If Next End Sub

  • VBAエクセル空白セル0の入力

    C列が空白となるまで、F列・・・L列の空白セルに0を代入する。 という処理を行いたく以下コードで実行をして ファイル種類をCSVにて、保存した後名前の変更で拡張子をTXTにすると データ入力された列の以降がカンマの羅列が「,,,,,,,,(改行)」の繰り返しで表示されてしまいます。 (CSV保存の後、視覚的に空白部分を行選択して削除するとなくなります。) どうすれば、このカンマが表示されなくなるでしょうか。 うまく説明できてないですが、アドバイス御願いします。 Dim i As Long i = 3 Do Until Cells(i, 3).Value = "" If Cells(i, 6).Value = "" Then Cells(i, 6).Value = "0" End If If Cells(i, 7).Value = "" Then Cells(i, 7).Value = "0" End If If Cells(i, 8).Value = "" Then Cells(i, 8).Value = "0" End If If Cells(i, 9).Value = "" Then Cells(i, 9).Value = "0" End If If Cells(i, 10).Value = "" Then Cells(i, 10).Value = "0" End If If Cells(i, 11).Value = "" Then Cells(i, 11).Value = "0" End If If Cells(i, 12).Value = "" Then Cells(i, 12).Value = "0" End If i = i + 1 Loop

専門家に質問してみよう